fix app layouts: remove style tags from content fragments, use component classes
This commit is contained in:
398
base-apps/com.mosis.messages/messages.lua
Normal file
398
base-apps/com.mosis.messages/messages.lua
Normal file
@@ -0,0 +1,398 @@
|
||||
-- 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 = [[<div class="conversation-unread">]] .. conv.unread .. [[</div>]]
|
||||
end
|
||||
|
||||
html = html .. [[
|
||||
<div class="conversation-item" onclick="openConversation(']] .. conv.id .. [[')">
|
||||
<div class="conversation-avatar" style="background-color: ]] .. color .. [[;">]] .. initial .. [[</div>
|
||||
<div class="conversation-content">
|
||||
<div class="conversation-header">
|
||||
<span class="conversation-name">]] .. conv.name .. [[</span>
|
||||
<span class="conversation-time">]] .. conv.time .. [[</span>
|
||||
</div>
|
||||
<div class="conversation-preview">]] .. conv.last_message .. [[</div>
|
||||
</div>
|
||||
]] .. unread_badge .. [[
|
||||
</div>
|
||||
]]
|
||||
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 .. [[
|
||||
<div class="message-bubble ]] .. class .. [[">]] .. msg.text .. [[</div>
|
||||
]]
|
||||
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
|
||||
Reference in New Issue
Block a user