-- messages.lua - Messages app functionality
-- Handles conversation list and individual chats
local messages_doc = nil
local conversations = {}
local current_conversation = nil
local current_messages = {}
-- Avatar colors
local avatar_colors = {
"#E91E63", "#9C27B0", "#673AB7", "#3F51B5", "#2196F3",
"#03A9F4", "#00BCD4", "#009688", "#4CAF50", "#FF9800"
}
local function getAvatarColor(name)
local sum = 0
for i = 1, #name do
sum = sum + string.byte(name, i)
end
return avatar_colors[(sum % #avatar_colors) + 1]
end
-- Initialize conversations data
local function initConversationsData()
conversations = {
{
id = "1",
name = "Alice Johnson",
phone = "+1 555-0101",
last_message = "Hey! Are you coming to the party tonight?",
time = "2:34 PM",
unread = 2,
messages = {
{sender = "them", text = "Hey!", time = "2:30 PM"},
{sender = "them", text = "What are you up to?", time = "2:31 PM"},
{sender = "me", text = "Not much, just working", time = "2:32 PM"},
{sender = "them", text = "Cool! There's a party at Mike's tonight", time = "2:33 PM"},
{sender = "them", text = "Hey! Are you coming to the party tonight?", time = "2:34 PM"},
}
},
{
id = "2",
name = "Bob Williams",
phone = "+1 555-0201",
last_message = "Thanks for the help yesterday!",
time = "1:15 PM",
unread = 0,
messages = {
{sender = "them", text = "Hey, can you help me with something?", time = "Yesterday"},
{sender = "me", text = "Sure, what do you need?", time = "Yesterday"},
{sender = "them", text = "I need help moving some furniture", time = "Yesterday"},
{sender = "me", text = "No problem, I'll be there at 2", time = "Yesterday"},
{sender = "them", text = "Thanks for the help yesterday!", time = "1:15 PM"},
}
},
{
id = "3",
name = "Carol Davis",
phone = "+1 555-0301",
last_message = "The meeting has been rescheduled to Friday",
time = "Yesterday",
unread = 0,
messages = {
{sender = "them", text = "Hi, are you free for a meeting tomorrow?", time = "Monday"},
{sender = "me", text = "Let me check my calendar", time = "Monday"},
{sender = "me", text = "Yes, I'm free at 3pm", time = "Monday"},
{sender = "them", text = "The meeting has been rescheduled to Friday", time = "Yesterday"},
}
},
{
id = "4",
name = "David Brown",
phone = "+1 555-0401",
last_message = "Can you send me the files?",
time = "Yesterday",
unread = 1,
messages = {
{sender = "them", text = "Hey, do you have the project files?", time = "Yesterday"},
{sender = "me", text = "Which ones?", time = "Yesterday"},
{sender = "them", text = "Can you send me the files?", time = "Yesterday"},
}
},
{
id = "5",
name = "Emma Wilson",
phone = "+1 555-0501",
last_message = "See you at the coffee shop!",
time = "Mon",
unread = 0,
messages = {
{sender = "me", text = "Want to grab coffee later?", time = "Mon"},
{sender = "them", text = "Sure! What time?", time = "Mon"},
{sender = "me", text = "How about 4pm at the usual place?", time = "Mon"},
{sender = "them", text = "See you at the coffee shop!", time = "Mon"},
}
},
{
id = "6",
name = "Frank Miller",
phone = "+1 555-0601",
last_message = "Great game last night!",
time = "Sun",
unread = 0,
messages = {
{sender = "them", text = "Did you watch the game?", time = "Sun"},
{sender = "me", text = "Yes! It was amazing!", time = "Sun"},
{sender = "them", text = "Great game last night!", time = "Sun"},
}
},
{
id = "7",
name = "Grace Lee",
phone = "+1 555-0701",
last_message = "Happy birthday! :)",
time = "Sat",
unread = 0,
messages = {
{sender = "them", text = "Happy birthday! :)", time = "Sat"},
{sender = "me", text = "Thank you so much! :)", time = "Sat"},
}
},
}
end
-- Initialize messages app
function initMessages(doc)
print("[Messages] Initializing...")
messages_doc = doc
initConversationsData()
renderConversations()
end
-- Render conversation list
function renderConversations()
if not messages_doc then return end
local container = messages_doc:GetElementById("conversations-list")
if not container then return end
local html = ""
for _, conv in ipairs(conversations) do
local color = getAvatarColor(conv.name)
local initial = conv.name:sub(1, 1):upper()
local unread_badge = ""
if conv.unread > 0 then
unread_badge = [[
]] .. conv.unread .. [[
]]
end
html = html .. [[
]] .. initial .. [[
]] .. conv.last_message .. [[
]] .. unread_badge .. [[
]]
end
container.inner_rml = html
end
-- Open a conversation
function openConversation(conv_id)
print("[Messages] Opening conversation: " .. conv_id)
-- Find conversation
for _, conv in ipairs(conversations) do
if conv.id == conv_id then
current_conversation = conv
current_messages = conv.messages
conv.unread = 0 -- Mark as read
break
end
end
if current_conversation then
-- Store for chat screen
if mosis and mosis.state then
mosis.state.set("current_chat", {
id = current_conversation.id,
name = current_conversation.name,
phone = current_conversation.phone
})
end
-- Navigate to chat
if navigateTo then
navigateTo("chat")
else
-- Inline chat view
showChatInline()
end
end
end
-- Show chat inline
function showChatInline()
if not messages_doc then return end
local list = messages_doc:GetElementById("conversations-container")
local chat = messages_doc:GetElementById("chat-container")
if list and chat then
list.style.display = "none"
chat.style.display = "flex"
renderChat()
end
end
-- Hide chat and return to list
function hideChat()
if not messages_doc then return end
local list = messages_doc:GetElementById("conversations-container")
local chat = messages_doc:GetElementById("chat-container")
if list and chat then
chat.style.display = "none"
list.style.display = "flex"
renderConversations() -- Refresh to update unread counts
end
current_conversation = nil
end
-- Render chat messages
function renderChat()
if not messages_doc or not current_conversation then return end
-- Update header
local name_el = messages_doc:GetElementById("chat-name")
local avatar_el = messages_doc:GetElementById("chat-avatar")
if name_el then
name_el.inner_rml = current_conversation.name
end
if avatar_el then
local color = getAvatarColor(current_conversation.name)
local initial = current_conversation.name:sub(1, 1):upper()
avatar_el.style["background-color"] = color
avatar_el.inner_rml = initial
end
-- Render messages
local container = messages_doc:GetElementById("chat-messages")
if not container then return end
local html = ""
for _, msg in ipairs(current_messages) do
local class = msg.sender == "me" and "message-sent" or "message-received"
html = html .. [[
]] .. msg.text .. [[
]]
end
container.inner_rml = html
-- Scroll to bottom
-- Note: RmlUi may need specific handling for scroll
end
-- Send a message
function sendMessage()
if not messages_doc or not current_conversation then return end
local input = messages_doc:GetElementById("message-input")
if not input then return end
local text = input.value or ""
if text == "" then return end
print("[Messages] Sending: " .. text)
-- Add message to current conversation
table.insert(current_messages, {
sender = "me",
text = text,
time = "Just now"
})
-- Update conversation preview
current_conversation.last_message = text
current_conversation.time = "Just now"
-- Clear input
input.value = ""
-- Re-render chat
renderChat()
-- Simulate reply after delay
if setTimeout then
setTimeout(function()
simulateReply()
end, 2000 + math.random(1000, 3000))
end
end
-- Simulate a reply
function simulateReply()
if not current_conversation then return end
local replies = {
"That's great!",
"I see",
"Sounds good!",
"Let me think about it",
"Sure thing!",
"OK!",
"Thanks!",
"Got it",
"Nice!",
"Interesting..."
}
local reply = replies[math.random(#replies)]
table.insert(current_messages, {
sender = "them",
text = reply,
time = "Just now"
})
current_conversation.last_message = reply
current_conversation.time = "Just now"
renderChat()
end
-- Handle input keypress (for Enter to send)
function onMessageKeypress(event)
if event.key == "Return" or event.key == "Enter" then
sendMessage()
return true
end
return false
end
-- Start new conversation
function newConversation()
print("[Messages] New conversation")
if showToast then
showToast("New message")
end
end
-- Search conversations
function searchConversations(query)
print("[Messages] Searching: " .. query)
-- TODO: Implement search filtering
end
-- Delete conversation
function deleteConversation(conv_id)
print("[Messages] Deleting conversation: " .. conv_id)
for i, conv in ipairs(conversations) do
if conv.id == conv_id then
table.remove(conversations, i)
break
end
end
renderConversations()
if showToast then
showToast("Conversation deleted")
end
end
-- Call contact from chat
function callFromChat()
if not current_conversation then return end
print("[Messages] Calling from chat: " .. current_conversation.name)
if mosis and mosis.state then
mosis.state.set("current_call", {
number = current_conversation.phone,
name = current_conversation.name
})
end
if navigateTo then
navigateTo("calling")
else
if showToast then
showToast("Calling " .. current_conversation.name)
end
end
end