fix app layouts: remove style tags from content fragments, use component classes
This commit is contained in:
227
base-apps/com.mosis.dialer/calling.lua
Normal file
227
base-apps/com.mosis.dialer/calling.lua
Normal file
@@ -0,0 +1,227 @@
|
||||
-- calling.lua - In-call screen functionality
|
||||
-- Handles call state, duration timer, and call controls
|
||||
|
||||
local calling_doc = nil
|
||||
local call_state = "connecting" -- connecting, active, ended
|
||||
local call_start_time = 0
|
||||
local call_duration = 0
|
||||
local timer_id = nil
|
||||
local is_muted = false
|
||||
local is_speaker = false
|
||||
local is_on_hold = false
|
||||
|
||||
-- Call info
|
||||
local call_number = ""
|
||||
local call_name = ""
|
||||
|
||||
-- Initialize calling screen
|
||||
function initCalling(doc)
|
||||
print("[Calling] Initializing...")
|
||||
calling_doc = doc
|
||||
|
||||
-- Get call info from state or use defaults
|
||||
if mosis and mosis.state then
|
||||
local call_info = mosis.state.get("current_call")
|
||||
if call_info then
|
||||
call_number = call_info.number or ""
|
||||
call_name = call_info.name or call_number
|
||||
end
|
||||
end
|
||||
|
||||
-- Fallback test data
|
||||
if call_number == "" then
|
||||
call_number = "+1 555-0101"
|
||||
call_name = "Alice Johnson"
|
||||
end
|
||||
|
||||
-- Update UI
|
||||
updateCallInfo()
|
||||
|
||||
-- Simulate connection after delay
|
||||
if setTimeout then
|
||||
setTimeout(function()
|
||||
setCallState("active")
|
||||
end, 2000)
|
||||
else
|
||||
setCallState("active")
|
||||
end
|
||||
end
|
||||
|
||||
-- Update call info display
|
||||
function updateCallInfo()
|
||||
if not calling_doc then return end
|
||||
|
||||
local name_el = calling_doc:GetElementById("call-name")
|
||||
local number_el = calling_doc:GetElementById("call-number")
|
||||
local status_el = calling_doc:GetElementById("call-status")
|
||||
local avatar_el = calling_doc:GetElementById("call-avatar")
|
||||
|
||||
if name_el then
|
||||
name_el.inner_rml = call_name
|
||||
end
|
||||
|
||||
if number_el then
|
||||
number_el.inner_rml = call_number
|
||||
end
|
||||
|
||||
if avatar_el then
|
||||
-- Get first letter for avatar
|
||||
local initial = call_name:sub(1, 1):upper()
|
||||
avatar_el.inner_rml = initial
|
||||
end
|
||||
end
|
||||
|
||||
-- Set call state
|
||||
function setCallState(state)
|
||||
print("[Calling] State changed to: " .. state)
|
||||
call_state = state
|
||||
|
||||
local status_el = calling_doc:GetElementById("call-status")
|
||||
local timer_el = calling_doc:GetElementById("call-timer")
|
||||
|
||||
if state == "connecting" then
|
||||
if status_el then
|
||||
status_el.inner_rml = "Calling..."
|
||||
end
|
||||
if timer_el then
|
||||
timer_el.style.display = "none"
|
||||
end
|
||||
elseif state == "active" then
|
||||
if status_el then
|
||||
status_el.inner_rml = "Connected"
|
||||
end
|
||||
if timer_el then
|
||||
timer_el.style.display = "block"
|
||||
end
|
||||
-- Start duration timer
|
||||
startCallTimer()
|
||||
elseif state == "ended" then
|
||||
if status_el then
|
||||
status_el.inner_rml = "Call ended"
|
||||
end
|
||||
stopCallTimer()
|
||||
-- Return to dialer after delay
|
||||
if setTimeout then
|
||||
setTimeout(function()
|
||||
if goBack then
|
||||
goBack()
|
||||
end
|
||||
end, 1500)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Start call duration timer
|
||||
function startCallTimer()
|
||||
call_start_time = os.time and os.time() or 0
|
||||
call_duration = 0
|
||||
|
||||
if setInterval then
|
||||
timer_id = setInterval(function()
|
||||
call_duration = call_duration + 1
|
||||
updateTimerDisplay()
|
||||
end, 1000)
|
||||
end
|
||||
end
|
||||
|
||||
-- Stop call timer
|
||||
function stopCallTimer()
|
||||
if timer_id and clearInterval then
|
||||
clearInterval(timer_id)
|
||||
timer_id = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Update timer display
|
||||
function updateTimerDisplay()
|
||||
local timer_el = calling_doc:GetElementById("call-timer")
|
||||
if timer_el then
|
||||
local minutes = math.floor(call_duration / 60)
|
||||
local seconds = call_duration % 60
|
||||
timer_el.inner_rml = string.format("%02d:%02d", minutes, seconds)
|
||||
end
|
||||
end
|
||||
|
||||
-- Toggle mute
|
||||
function toggleMute()
|
||||
is_muted = not is_muted
|
||||
print("[Calling] Mute: " .. tostring(is_muted))
|
||||
|
||||
local mute_btn = calling_doc:GetElementById("btn-mute")
|
||||
if mute_btn then
|
||||
if is_muted then
|
||||
mute_btn:SetClass("active", true)
|
||||
else
|
||||
mute_btn:SetClass("active", false)
|
||||
end
|
||||
end
|
||||
|
||||
if showToast then
|
||||
showToast(is_muted and "Muted" or "Unmuted")
|
||||
end
|
||||
end
|
||||
|
||||
-- Toggle speaker
|
||||
function toggleSpeaker()
|
||||
is_speaker = not is_speaker
|
||||
print("[Calling] Speaker: " .. tostring(is_speaker))
|
||||
|
||||
local speaker_btn = calling_doc:GetElementById("btn-speaker")
|
||||
if speaker_btn then
|
||||
if is_speaker then
|
||||
speaker_btn:SetClass("active", true)
|
||||
else
|
||||
speaker_btn:SetClass("active", false)
|
||||
end
|
||||
end
|
||||
|
||||
if showToast then
|
||||
showToast(is_speaker and "Speaker on" or "Speaker off")
|
||||
end
|
||||
end
|
||||
|
||||
-- Toggle hold
|
||||
function toggleHold()
|
||||
is_on_hold = not is_on_hold
|
||||
print("[Calling] Hold: " .. tostring(is_on_hold))
|
||||
|
||||
local hold_btn = calling_doc:GetElementById("btn-hold")
|
||||
if hold_btn then
|
||||
if is_on_hold then
|
||||
hold_btn:SetClass("active", true)
|
||||
else
|
||||
hold_btn:SetClass("active", false)
|
||||
end
|
||||
end
|
||||
|
||||
local status_el = calling_doc:GetElementById("call-status")
|
||||
if status_el then
|
||||
if is_on_hold then
|
||||
status_el.inner_rml = "On hold"
|
||||
else
|
||||
status_el.inner_rml = "Connected"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Show dialpad
|
||||
function showDialpad()
|
||||
print("[Calling] Show dialpad")
|
||||
if showToast then
|
||||
showToast("Dialpad")
|
||||
end
|
||||
end
|
||||
|
||||
-- Add call (conference)
|
||||
function addCall()
|
||||
print("[Calling] Add call")
|
||||
if showToast then
|
||||
showToast("Add call")
|
||||
end
|
||||
end
|
||||
|
||||
-- End call
|
||||
function endCall()
|
||||
print("[Calling] Ending call")
|
||||
setCallState("ended")
|
||||
end
|
||||
@@ -4,45 +4,30 @@
|
||||
<link type="text/rcss" href="../../ui/theme.rcss"/>
|
||||
<link type="text/rcss" href="../../ui/components.rcss"/>
|
||||
<script src="../../scripts/navigation.lua"></script>
|
||||
<script src="../../scripts/phone.lua"></script>
|
||||
<script src="calling.lua"></script>
|
||||
<title>Calling</title>
|
||||
<style>
|
||||
.calling-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(180deg, #1a237e 0%, #121212 100%);
|
||||
background: linear-gradient(180deg, #1a237e 0%, #000000 100%);
|
||||
background-color: #1a237e;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.calling-status {
|
||||
margin-top: 80px;
|
||||
font-size: 18px;
|
||||
color: #4CAF50;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 2px;
|
||||
.calling-header {
|
||||
padding-top: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.calling-name {
|
||||
margin-top: 24px;
|
||||
font-size: 32px;
|
||||
font-weight: 300;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.calling-number {
|
||||
margin-top: 8px;
|
||||
font-size: 16px;
|
||||
color: #B3B3B3;
|
||||
}
|
||||
|
||||
.calling-avatar {
|
||||
margin-top: 48px;
|
||||
.call-avatar {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 60px;
|
||||
background-color: #BB86FC;
|
||||
margin: 0 auto 24px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -50,77 +35,157 @@
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.calling-actions {
|
||||
position: absolute;
|
||||
bottom: 120px;
|
||||
display: flex;
|
||||
gap: 48px;
|
||||
.call-name {
|
||||
font-size: 32px;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.call-action-btn {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 32px;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
.call-number {
|
||||
font-size: 18px;
|
||||
color: #B3B3B3;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.call-status {
|
||||
font-size: 18px;
|
||||
color: #4CAF50;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.call-timer {
|
||||
font-size: 24px;
|
||||
color: #FFFFFF;
|
||||
font-weight: 300;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.calling-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.call-controls {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
padding: 40px;
|
||||
gap: 32px;
|
||||
max-width: 320px;
|
||||
}
|
||||
|
||||
.call-control-btn {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 36px;
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.call-action-btn:hover {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
.call-control-btn:hover {
|
||||
background-color: rgba(255, 255, 255, 0.25);
|
||||
}
|
||||
|
||||
.call-action-btn img {
|
||||
.call-control-btn.active {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.call-control-btn img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.call-control-label {
|
||||
font-size: 12px;
|
||||
color: #FFFFFF;
|
||||
margin-top: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.call-control-btn.active .call-control-label {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.end-call-container {
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.end-call-btn {
|
||||
position: absolute;
|
||||
bottom: 40px;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 36px;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 40px;
|
||||
background-color: #F44336;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.end-call-btn:hover {
|
||||
background-color: #E53935;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.end-call-btn:active {
|
||||
background-color: #C62828;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.end-call-btn img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
pointer-events: none;
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="calling-screen">
|
||||
<div class="calling-status">Calling...</div>
|
||||
<div class="calling-name" id="calling-name">Unknown</div>
|
||||
<div class="calling-number" id="calling-number"></div>
|
||||
<body class="calling-screen" onload="initCalling(document)">
|
||||
<!-- Caller Info -->
|
||||
<div class="calling-header">
|
||||
<div class="call-avatar" id="call-avatar">A</div>
|
||||
<div class="call-name" id="call-name">Alice Johnson</div>
|
||||
<div class="call-number" id="call-number">+1 555-0101</div>
|
||||
<div class="call-status" id="call-status">Calling...</div>
|
||||
<div class="call-timer" id="call-timer">00:00</div>
|
||||
</div>
|
||||
|
||||
<div class="calling-avatar" id="calling-avatar">?</div>
|
||||
<!-- Spacer -->
|
||||
<div class="calling-content"></div>
|
||||
|
||||
<div class="calling-actions">
|
||||
<div class="call-action-btn">
|
||||
<img src="../../icons/dialpad.tga"/>
|
||||
<!-- Call Controls -->
|
||||
<div class="call-controls">
|
||||
<div id="btn-mute" class="call-control-btn" onclick="toggleMute()">
|
||||
<img src="../../icons/mic_off.tga"/>
|
||||
<span class="call-control-label">Mute</span>
|
||||
</div>
|
||||
<div class="call-action-btn">
|
||||
<img src="../../icons/contacts.tga"/>
|
||||
<div id="btn-keypad" class="call-control-btn" onclick="showDialpad()">
|
||||
<img src="../../icons/dialpad.tga"/>
|
||||
<span class="call-control-label">Keypad</span>
|
||||
</div>
|
||||
<div id="btn-speaker" class="call-control-btn" onclick="toggleSpeaker()">
|
||||
<img src="../../icons/volume.tga"/>
|
||||
<span class="call-control-label">Speaker</span>
|
||||
</div>
|
||||
<div id="btn-add" class="call-control-btn" onclick="addCall()">
|
||||
<img src="../../icons/add.tga"/>
|
||||
<span class="call-control-label">Add call</span>
|
||||
</div>
|
||||
<div id="btn-hold" class="call-control-btn" onclick="toggleHold()">
|
||||
<img src="../../icons/pause.tga"/>
|
||||
<span class="call-control-label">Hold</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="end-call-btn" onclick="endCall()">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
<!-- End Call Button -->
|
||||
<div class="end-call-container">
|
||||
<div class="end-call-btn" onclick="endCall()">
|
||||
<img src="../../icons/call_end.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</rml>
|
||||
|
||||
235
base-apps/com.mosis.dialer/dialer.lua
Normal file
235
base-apps/com.mosis.dialer/dialer.lua
Normal file
@@ -0,0 +1,235 @@
|
||||
-- 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 = '<span style="color: #666666;">Enter number</span>'
|
||||
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 .. [[
|
||||
<div class="call-history-item" onclick="callNumber(']] .. call.number .. [[')">
|
||||
<div class="call-history-icon" style="background-color: ]] .. icon_color .. [[;">
|
||||
<img src="../../icons/]] .. icon .. [[" style="width: 24px; height: 24px;"/>
|
||||
</div>
|
||||
<div class="call-history-info">
|
||||
<div class="call-history-name">]] .. call.name .. [[</div>
|
||||
<div class="call-history-meta">]] .. call.type .. " - " .. call.time .. [[</div>
|
||||
</div>
|
||||
<div class="call-history-time">]] .. duration_text .. [[</div>
|
||||
</div>
|
||||
]]
|
||||
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
|
||||
@@ -6,6 +6,7 @@
|
||||
<link type="text/rcss" href="../../ui/layout.rcss"/>
|
||||
<script src="../../scripts/navigation.lua"></script>
|
||||
<script src="../../scripts/layout.lua"></script>
|
||||
<script src="dialer.lua"></script>
|
||||
<title>Phone</title>
|
||||
<style>
|
||||
.dialer-content {
|
||||
@@ -14,6 +15,61 @@
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Keypad content */
|
||||
#keypad-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Recent calls content */
|
||||
#recent-content {
|
||||
flex: 1;
|
||||
display: none;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.call-history-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.call-history-item:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.call-history-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 20px;
|
||||
margin-right: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.call-history-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.call-history-name {
|
||||
font-size: 16px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.call-history-meta {
|
||||
font-size: 14px;
|
||||
color: #888888;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.call-history-time {
|
||||
font-size: 14px;
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
/* Phone app bottom tabs */
|
||||
.phone-tabs {
|
||||
height: 72px;
|
||||
@@ -50,7 +106,7 @@
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="app-screen" onload="initLayout(document)" data-model="phone">
|
||||
<body class="app-screen" onload="initLayout(document); initDialer(document)">
|
||||
<!-- System Status Bar -->
|
||||
<div class="system-status-bar">
|
||||
<span id="status-time" class="system-status-time">12:30</span>
|
||||
@@ -71,84 +127,96 @@
|
||||
|
||||
<!-- Dialer Content -->
|
||||
<div class="dialer-content">
|
||||
<!-- Dial Display -->
|
||||
<div class="dial-display">{{ dial_number }}</div>
|
||||
<!-- Keypad View -->
|
||||
<div id="keypad-content">
|
||||
<!-- Dial Display -->
|
||||
<div class="dial-display" id="dial-display">
|
||||
<span style="color: #666666;">Enter number</span>
|
||||
</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>
|
||||
<!-- Dial Pad -->
|
||||
<div class="dial-pad">
|
||||
<div class="dial-key" onclick="dial_press('1')">
|
||||
<span class="dial-key-number">1</span>
|
||||
<span class="dial-key-letters"></span>
|
||||
</div>
|
||||
<div class="dial-key" onclick="dial_press('2')">
|
||||
<span class="dial-key-number">2</span>
|
||||
<span class="dial-key-letters">ABC</span>
|
||||
</div>
|
||||
<div class="dial-key" onclick="dial_press('3')">
|
||||
<span class="dial-key-number">3</span>
|
||||
<span class="dial-key-letters">DEF</span>
|
||||
</div>
|
||||
<div class="dial-key" onclick="dial_press('4')">
|
||||
<span class="dial-key-number">4</span>
|
||||
<span class="dial-key-letters">GHI</span>
|
||||
</div>
|
||||
<div class="dial-key" onclick="dial_press('5')">
|
||||
<span class="dial-key-number">5</span>
|
||||
<span class="dial-key-letters">JKL</span>
|
||||
</div>
|
||||
<div class="dial-key" onclick="dial_press('6')">
|
||||
<span class="dial-key-number">6</span>
|
||||
<span class="dial-key-letters">MNO</span>
|
||||
</div>
|
||||
<div class="dial-key" onclick="dial_press('7')">
|
||||
<span class="dial-key-number">7</span>
|
||||
<span class="dial-key-letters">PQRS</span>
|
||||
</div>
|
||||
<div class="dial-key" onclick="dial_press('8')">
|
||||
<span class="dial-key-number">8</span>
|
||||
<span class="dial-key-letters">TUV</span>
|
||||
</div>
|
||||
<div class="dial-key" onclick="dial_press('9')">
|
||||
<span class="dial-key-number">9</span>
|
||||
<span class="dial-key-letters">WXYZ</span>
|
||||
</div>
|
||||
<div class="dial-key" onclick="dial_press('*')">
|
||||
<span class="dial-key-number">*</span>
|
||||
<span class="dial-key-letters"></span>
|
||||
</div>
|
||||
<div class="dial-key" onclick="dial_press('0')">
|
||||
<span class="dial-key-number">0</span>
|
||||
<span class="dial-key-letters">+</span>
|
||||
</div>
|
||||
<div class="dial-key" onclick="dial_press('#')">
|
||||
<span class="dial-key-number">#</span>
|
||||
<span class="dial-key-letters"></span>
|
||||
</div>
|
||||
</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" onclick="make_call()">
|
||||
<img src="../../icons/call_small.tga" style="width: 32px; height: 32px; pointer-events: none;"/>
|
||||
</div>
|
||||
<div class="btn-icon" onclick="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;"/>
|
||||
<!-- Recent Calls View -->
|
||||
<div id="recent-content">
|
||||
<div id="recent-list">
|
||||
<!-- Populated by Lua -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Phone App Bottom Tabs -->
|
||||
<div class="phone-tabs">
|
||||
<div class="phone-tab active">
|
||||
<div id="tab-keypad" class="phone-tab active" onclick="switchTab('keypad')">
|
||||
<img src="../../icons/dialpad.tga"/>
|
||||
<span>Keypad</span>
|
||||
</div>
|
||||
<div class="phone-tab">
|
||||
<div id="tab-recent" class="phone-tab" onclick="switchTab('recent')">
|
||||
<img src="../../icons/history.tga"/>
|
||||
<span>Recent</span>
|
||||
</div>
|
||||
<div class="phone-tab" onclick="navigateTo('contacts')">
|
||||
<div id="tab-contacts" class="phone-tab" onclick="navigateTo('contacts')">
|
||||
<img src="../../icons/contacts.tga"/>
|
||||
<span>Contacts</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user