mime-chat/src/render/components/controllers/messenger.control.ts
2021-06-08 21:21:11 -05:00

143 lines
No EOL
3.7 KiB
TypeScript

import { ref } from 'vue';
import invokeSavedMessages from "@/render/ipc";
import useScroll from "@/render/composables/scroll";
const messages = ref(new Map());
function getTimeStamp(): number {
const currentdate = new Date();
return currentdate.getTime();
}
const newViewMessage = (message: Message): ViewMessage => {
return {
text: message.text,
context: message.context,
audio: message.audio,
from: message.from,
uid: message.uid,
time: getTimeStamp(),
isChild: "none",
seen: false,
newMessage: false
};
}
const addMessage = (message: Message, newMessage=false) => {
const viewMessage = newViewMessage(message);
if (newMessage) viewMessage.newMessage = true;
messages.value.set(viewMessage.uid, viewMessage);
}
const updateMessage = (message: Message) => {
const viewMessage = messages.value.get(message.uid);
viewMessage.context = message.context;
viewMessage.text = message.text;
}
const loadSavedMessages = async () => {
const messageData = await invokeSavedMessages();
messages.value = new Map(Object.entries(messageData));
}
const saveMessages = () => {
const messageData = Object.fromEntries(messages.value);
// must save to json.
}
const pruneMessages = (limit=200) => {
if (messages.value.size >= limit) {
const oldest = Array.from(messages.value.keys()).shift();
messages.value.delete(oldest);
}
}
const updateGrouping = () => {
const isSimmilar = (messageA: ViewMessage, messageB: ViewMessage) => {
if ((Math.abs(messageA.time - messageB.time) < 20000) && (messageA.from == messageB.from) && (messageA.context == messageB.context)) {
return true
}
return false
}
const refs = Array.from(messages.value.keys())
// Get the last three messages.
const first = messages.value.get(refs[refs.length - 1])
const second = messages.value.get(refs[refs.length - 2])
const third = messages.value.get(refs[refs.length - 3])
// If messages are simmilar, update the classes.
if ((first) && (second)) {
if (isSimmilar(first, second)) {
first.isChild = "last" // i.e. last in group.
second.isChild = "first"
if (third) {
if ((third.isChild == "first") || (third.isChild == "middle")) {
second.isChild = "middle"
}
}
}
}
}
export default function useMessages() {
const { updateScrollRef, adjustScroll } = useScroll("messenger");
/* Given new message object, update the view accordingly */
const updateMessageView = (newMessages: Message[]) => {
const bottom = updateScrollRef(); // see if the user is scrolled down
// take each message and apply view
newMessages.forEach((message: Message) => {
// add or update message depending
if (messages.value.has(message.uid)) {
updateMessage(message);
} else addMessage(message);
pruneMessages(); // pop off old messages from view
updateGrouping(); // group like message together
if (bottom) adjustScroll(); // only scroll if user was at bottom
saveMessages();
});
}
return {
messages,
updateMessageView,
loadSavedMessages
}
}
// // Seed message view with message history.
// const prepMessageView = async (newMessages: Message[]) => {
// console.log("MSGR:Prepping messenger view.")
// // Load and render saved messages and immediately scroll to bottom.
// await loadSavedMessages();
// setTimeout(setScroll.bind(false), 10);
// // Render new messages, then wait 1s to scroll.
// if (newMessages.length) {
// console.log("MSGR:Adding new messages")
// newMessages.forEach(message => {
// addMessage(message, true);
// })
// setTimeout(setScroll.bind(true), 1000);
// }
// }