diff --git a/src/main/assets/apps/shell/shell.lua b/src/main/assets/apps/shell/shell.lua index 95b97f2..1e80610 100644 --- a/src/main/assets/apps/shell/shell.lua +++ b/src/main/assets/apps/shell/shell.lua @@ -30,8 +30,8 @@ function initShell(doc) -- Update time display updateTime() - -- Load home screen by default - loadAppContent_internal("home", "apps/home/home_content.rml") + -- Load home screen by default (skip animation on initial load) + loadAppContent_internal("home", "apps/home/home_content.rml", true) print("[Shell] Shell initialized") end @@ -46,8 +46,8 @@ end -- ===== APP LOADING ===== --- Internal function to load app content -function loadAppContent_internal(app_id, app_path) +-- Internal function to load app content with optional animation +function loadAppContent_internal(app_id, app_path, skip_animation) if not app_container then print("[Shell] ERROR: No app container") return false @@ -68,6 +68,18 @@ function loadAppContent_internal(app_id, app_path) current_app_path = app_path print("[Shell] App loaded: " .. app_id) + -- Play opening animation (unless skipped for initial load) + if not skip_animation then + app_container:SetClass("app-opening", true) + app_container:SetClass("app-closing", false) + -- Remove animation class after it completes + if setTimeout then + setTimeout(function() + app_container:SetClass("app-opening", false) + end, 300) + end + end + -- If home was loaded, populate apps dynamically if app_id == "home" then populateHomeApps() @@ -126,6 +138,21 @@ end -- ===== NAVIGATION ===== +-- Play closing animation then execute callback +local function playCloseAnimation(callback) + if app_container and setTimeout then + app_container:SetClass("app-closing", true) + app_container:SetClass("app-opening", false) + setTimeout(function() + app_container:SetClass("app-closing", false) + if callback then callback() end + end, 200) + else + -- No animation support, execute immediately + if callback then callback() end + end +end + -- Go back to previous app function shellGoBack() print("[Shell] goBack called (history depth: " .. #nav_history .. ")") @@ -139,17 +166,20 @@ function shellGoBack() local previous = table.remove(nav_history) print("[Shell] Going back to: " .. previous.app_id) - -- Don't push to history when going back - local temp_app = current_app - current_app = nil - current_app_path = nil + -- Play closing animation, then load previous app + playCloseAnimation(function() + -- Don't push to history when going back + local temp_app = current_app + current_app = nil + current_app_path = nil - local success = loadAppContent_internal(previous.app_id, previous.app_path) - if not success then - -- Restore state on failure - current_app = temp_app - end - return success + local success = loadAppContent_internal(previous.app_id, previous.app_path) + if not success then + -- Restore state on failure + current_app = temp_app + end + end) + return true else print("[Shell] No history - already at root") if current_app ~= "home" then @@ -171,10 +201,12 @@ function shellGoHome() -- Clear history nav_history = {} - -- Load home - current_app = nil - current_app_path = nil - loadAppContent_internal("home", "apps/home/home_content.rml") + -- Play closing animation, then load home + playCloseAnimation(function() + current_app = nil + current_app_path = nil + loadAppContent_internal("home", "apps/home/home_content.rml") + end) end -- Show recents (placeholder) @@ -209,6 +241,8 @@ end -- ===== TOASTS ===== +local active_toast_id = nil + function showToast(message, type) type = type or "default" @@ -218,24 +252,39 @@ function showToast(message, type) return end - local class = "toast" - if type == "success" then - class = "toast toast-success" - elseif type == "error" then - class = "toast toast-error" - elseif type == "warning" then - class = "toast toast-warning" + -- Cancel any pending hide timer + if active_toast_id and clearTimeout then + clearTimeout(active_toast_id) + active_toast_id = nil end - -- Clear existing toasts and add new one - local toast_html = '