view src/lib/Chat.luan @ 64:bc9f452ee168

minor
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 05 Mar 2025 21:43:11 -0700
parents afd5ab5b02a2
children a47036fd0158
line wrap: on
line source

local Luan = require "luan:Luan.luan"
local error = Luan.error
local ipairs = Luan.ipairs or error()
local Time = require "luan:Time.luan"
local time_now = Time.now or error()
local Table = require "luan:Table.luan"
local sort = Table.sort or error()
local concat = Table.concat or error()
local Http = require "luan:http/Http.luan"
local Db = require "site:/lib/Db.luan"
local run_in_transaction = Db.run_in_transaction or error()
local Utils = require "site:/lib/Utils.luan"
local base_url = Utils.base_url or error()


local Chat = {}

local function from_doc(doc)
	doc.type == "chat" or error "wrong type"
	return Chat.new {
		id = doc.id
		user_ids = doc.chat_user_ids
		updated = doc.chat_updated
		key = doc.chat_key
	}
end

local function to_doc(chat)
	return {
		type = "chat"
		id = chat.id
		chat_user_ids = chat.user_ids or error()
		chat_updated = chat.updated or error()
		chat_key = chat.key or error()
	}
end

local function get_chat_key(user_ids)
	#user_ids > 1 or error "You can't chat with yourself"
	sort(user_ids)
	return concat(user_ids,"~")
end

function Chat.new(chat)
	chat.updated = chat.updated or time_now()
	chat.key = chat.key or get_chat_key(chat.user_ids)

	function chat.save()
		local doc = to_doc(chat)
		Db.save(doc)
		chat.id = doc.id
	end

	function chat.delete()
		run_in_transaction( function()
			local id = chat.id
			Db.delete("post_chat_id:"..id)
			Db.delete("chatuser_chat_id:"..id)
			Db.delete("id:"..id)
		end )
	end

	function chat.http_push(message)
		local url = base_url().."/chat/"..chat.id
		Http.push(url,message)
	end

	function chat.other_user_id(my_id)
		for _, user_id in ipairs(chat.user_ids) do
			if user_id ~= my_id then
				return user_id
			end
		end
		error()
	end

	local function get_chatuser_key(user)
		return chat.id.."~"..user.id
	end

	function chat.unread(user)
		local doc = Db.get_document("chatuser_key:"..get_chatuser_key(user))
		local read_date = doc and doc.read_date or 0
		return Db.count("+post_chat_id:"..chat.id.." +post_date:["..read_date.." TO *]")
	end

	function chat.read(user)
		run_in_transaction( function()
			local chatuser_key = get_chatuser_key(user)
			local doc = Db.get_document("chatuser_key:"..chatuser_key) or {
				type = "chatuser"
				chatuser_key = chatuser_key
				chatuser_chat_id = chat.id or error()
			}
			doc.read_date = time_now()
			Db.save(doc)
		end )
	end

	return chat
end

function Chat.search(query,sort,rows)
	rows = rows or 1000000
	local chats = {}
	local docs = Db.search(query,1,rows,{sort=sort})
	for _, doc in ipairs(docs) do
		chats[#chats+1] = from_doc(doc)
	end
	return chats
end

function Chat.get_by_id(id)
	local doc = Db.get_document("id:"..id)
	return doc and doc.type=="chat" and from_doc(doc) or nil
end

function Chat.get_by_user_ids(user_ids)
	local key = get_chat_key(user_ids)
	local doc = Db.get_document("chat_key:"..key)
	return doc and from_doc(doc)
end

return Chat