-- dialer.lua - Phone dialer functionality -- Handles dial pad input, call management, and call history local dialer_doc = nil local dial_number = "" local call_history = {} local current_tab = "keypad" -- keypad, recent, contacts -- Sample call history data local function initCallHistory() call_history = { {name = "Alice Johnson", number = "+1 555-0101", type = "incoming", time = "2:34 PM", duration = "5:23"}, {name = "Bob Williams", number = "+1 555-0201", type = "outgoing", time = "1:15 PM", duration = "2:45"}, {name = "Carol Davis", number = "+1 555-0301", type = "missed", time = "Yesterday", duration = nil}, {name = "David Brown", number = "+1 555-0401", type = "incoming", time = "Yesterday", duration = "12:30"}, {name = "Emma Wilson", number = "+1 555-0501", type = "outgoing", time = "Mon", duration = "3:15"}, {name = "+1 555-9999", number = "+1 555-9999", type = "missed", time = "Mon", duration = nil}, {name = "John Doe", number = "+1 555-1234", type = "incoming", time = "Sun", duration = "8:42"}, } end -- Initialize dialer function initDialer(doc) print("[Dialer] Initializing...") dialer_doc = doc dial_number = "" initCallHistory() updateDialDisplay() end -- Update the dial display function updateDialDisplay() if not dialer_doc then return end local display = dialer_doc:GetElementById("dial-display") if display then if dial_number == "" then display.inner_rml = 'Enter number' else -- Format number for display local formatted = formatPhoneNumber(dial_number) display.inner_rml = formatted end end end -- Format phone number for display function formatPhoneNumber(number) local len = #number if len <= 3 then return number elseif len <= 6 then return number:sub(1,3) .. "-" .. number:sub(4) elseif len <= 10 then return "(" .. number:sub(1,3) .. ") " .. number:sub(4,6) .. "-" .. number:sub(7) else return "+1 (" .. number:sub(1,3) .. ") " .. number:sub(4,6) .. "-" .. number:sub(7,10) end end -- Handle dial key press function dial_press(key) print("[Dialer] Key pressed: " .. key) if #dial_number < 15 then dial_number = dial_number .. key updateDialDisplay() -- Play haptic/sound feedback if available if mosis and mosis.haptic then mosis.haptic.vibrate(10) end end end -- Handle backspace function dial_backspace() if #dial_number > 0 then dial_number = dial_number:sub(1, -2) updateDialDisplay() end end -- Clear dial number function dial_clear() dial_number = "" updateDialDisplay() end -- Make a call function make_call() if dial_number == "" then print("[Dialer] Cannot call: no number entered") if showToast then showToast("Enter a number to call") end return end print("[Dialer] Calling: " .. dial_number) -- Add to call history table.insert(call_history, 1, { name = dial_number, number = dial_number, type = "outgoing", time = "Just now", duration = nil }) -- Navigate to calling screen if navigateTo then -- Store call info for the calling screen if mosis and mosis.state then mosis.state.set("current_call", { number = dial_number, name = getContactName(dial_number), start_time = os.time and os.time() or 0 }) end navigateTo("calling") else -- Fallback: load calling screen directly local calling_path = dialer_doc:GetSourceURL():gsub("dialer.rml", "calling.rml") if mosis and mosis.loadDocument then mosis.loadDocument(calling_path) end end end -- Get contact name by number (returns number if not found) function getContactName(number) for _, call in ipairs(call_history) do if call.number == number and call.name ~= number then return call.name end end return number end -- Switch tabs function switchTab(tab_name) print("[Dialer] Switching to tab: " .. tab_name) current_tab = tab_name -- Update tab UI local tabs = {"keypad", "recent", "contacts"} for _, tab in ipairs(tabs) do local tab_el = dialer_doc:GetElementById("tab-" .. tab) if tab_el then if tab == tab_name then tab_el:SetClass("active", true) else tab_el:SetClass("active", false) end end end -- Show/hide content local keypad_content = dialer_doc:GetElementById("keypad-content") local recent_content = dialer_doc:GetElementById("recent-content") if keypad_content then keypad_content.style.display = (tab_name == "keypad") and "flex" or "none" end if recent_content then recent_content.style.display = (tab_name == "recent") and "block" or "none" end -- Render recent calls if switching to that tab if tab_name == "recent" then renderCallHistory() end end -- Render call history function renderCallHistory() local container = dialer_doc:GetElementById("recent-list") if not container then return end local html = "" for _, call in ipairs(call_history) do local icon_color = "#4CAF50" -- incoming = green local icon = "phone.tga" if call.type == "outgoing" then icon_color = "#2196F3" -- blue icon = "call_made.tga" elseif call.type == "missed" then icon_color = "#F44336" -- red icon = "call_missed.tga" end local duration_text = call.duration or "Missed" html = html .. [[
]] .. call.name .. [[
]] .. call.type .. " - " .. call.time .. [[
]] .. duration_text .. [[
]] end container.inner_rml = html end -- Call a number from history function callNumber(number) dial_number = number:gsub("[^%d+]", "") -- Remove non-digit chars except + updateDialDisplay() switchTab("keypad") make_call() end -- Long press on 0 for + function dial_long_press_zero() if dial_number == "" or dial_number:sub(-1) ~= "0" then dial_press("+") else -- Replace last 0 with + dial_number = dial_number:sub(1, -2) .. "+" updateDialDisplay() end end -- Long press on * for pause function dial_long_press_star() dial_press(",") -- Comma is standard pause character end