143 lines
No EOL
3.7 KiB
TypeScript
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);
|
|
|
|
// }
|
|
// }
|