2022-02-24 14:14:59 +00:00
|
|
|
|
/*
|
|
|
|
|
* This file contains code to map data structures to actual HTML elements.
|
|
|
|
|
* It is mostly functional and boring and it does not include any sliding sync specific data.
|
|
|
|
|
* In other words, if you want to learn about sliding sync, this isn't the file to look at.
|
|
|
|
|
*/
|
2022-02-23 12:16:22 +00:00
|
|
|
|
|
|
|
|
|
const membershipChangeText = (ev) => {
|
|
|
|
|
const prevContent = (ev.unsigned || {}).prev_content || {};
|
|
|
|
|
const prevMembership = prevContent.membership || "leave";
|
|
|
|
|
const nowMembership = ev.content.membership;
|
|
|
|
|
if (nowMembership != prevMembership) {
|
|
|
|
|
switch (nowMembership) {
|
|
|
|
|
case "join":
|
|
|
|
|
return ev.state_key + " joined the room";
|
|
|
|
|
case "leave":
|
|
|
|
|
return ev.state_key + " left the room";
|
|
|
|
|
case "ban":
|
|
|
|
|
return ev.sender + " banned " + ev.state_key + " from the room";
|
|
|
|
|
case "invite":
|
|
|
|
|
return ev.sender + " invited " + ev.state_key + " to the room";
|
|
|
|
|
case "knock":
|
|
|
|
|
return ev.state_key + " knocked on the room";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (nowMembership == prevMembership && nowMembership == "join") {
|
|
|
|
|
// display name or avatar change
|
|
|
|
|
if (prevContent.displayname !== ev.content.displayname) {
|
2022-02-23 19:26:38 +00:00
|
|
|
|
return (
|
|
|
|
|
ev.state_key + " set their name to " + ev.content.displayname
|
|
|
|
|
);
|
2022-02-23 12:16:22 +00:00
|
|
|
|
}
|
|
|
|
|
if (prevContent.avatar_url !== ev.content.avatar_url) {
|
|
|
|
|
return ev.state_key + " changed their profile picture";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ev.type + " event";
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-24 14:43:45 +00:00
|
|
|
|
const textForEvent = (ev) => {
|
2022-02-23 12:16:22 +00:00
|
|
|
|
let body = "";
|
|
|
|
|
switch (ev.type) {
|
|
|
|
|
case "m.room.message":
|
|
|
|
|
body = ev.content.body;
|
|
|
|
|
break;
|
|
|
|
|
case "m.room.member":
|
|
|
|
|
body = membershipChangeText(ev);
|
|
|
|
|
break;
|
|
|
|
|
case "m.reaction":
|
|
|
|
|
body = "reacted with " + (ev.content["m.relates_to"] || {}).key;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
body = ev.type + " event";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return body;
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-24 14:43:45 +00:00
|
|
|
|
const randomName = (i, long) => {
|
|
|
|
|
if (i % 17 === 0) {
|
|
|
|
|
return long
|
|
|
|
|
? "Ever have that feeling where you’re not sure if you’re awake or dreaming?"
|
|
|
|
|
: "There is no spoon";
|
|
|
|
|
} else if (i % 13 === 0) {
|
|
|
|
|
return long
|
|
|
|
|
? "Choice is an illusion created between those with power and those without."
|
|
|
|
|
: "Get Up Trinity";
|
|
|
|
|
} else if (i % 11 === 0) {
|
|
|
|
|
return long
|
|
|
|
|
? "That’s how it is with people. Nobody cares how it works as long as it works."
|
|
|
|
|
: "I know kung fu";
|
|
|
|
|
} else if (i % 7 === 0) {
|
|
|
|
|
return long
|
|
|
|
|
? "The body cannot live without the mind."
|
|
|
|
|
: "Free your mind";
|
|
|
|
|
} else if (i % 5 === 0) {
|
|
|
|
|
return long
|
|
|
|
|
? "Perhaps we are asking the wrong questions…"
|
|
|
|
|
: "Agent Smith";
|
|
|
|
|
} else if (i % 3 === 0) {
|
|
|
|
|
return long
|
|
|
|
|
? "You've been living in a dream world, Neo."
|
|
|
|
|
: "Mr Anderson";
|
|
|
|
|
} else {
|
|
|
|
|
return long ? "Mr. Wizard, get me the hell out of here! " : "Morpheus";
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-23 12:16:22 +00:00
|
|
|
|
const zeroPad = (n) => {
|
|
|
|
|
if (n < 10) {
|
|
|
|
|
return "0" + n;
|
|
|
|
|
}
|
|
|
|
|
return n;
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-24 14:43:45 +00:00
|
|
|
|
const formatTimestamp = (originServerTs) => {
|
2022-02-23 12:16:22 +00:00
|
|
|
|
const d = new Date(originServerTs);
|
|
|
|
|
return (
|
|
|
|
|
d.toDateString() +
|
|
|
|
|
" " +
|
|
|
|
|
zeroPad(d.getHours()) +
|
|
|
|
|
":" +
|
|
|
|
|
zeroPad(d.getMinutes()) +
|
|
|
|
|
":" +
|
|
|
|
|
zeroPad(d.getSeconds())
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2022-03-07 17:29:36 +00:00
|
|
|
|
const mxcToUrl = (syncv2ServerUrl, mxc) => {
|
2022-02-24 14:43:45 +00:00
|
|
|
|
const path = mxc.substr("mxc://".length);
|
|
|
|
|
if (!path) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
return `${syncv2ServerUrl}/_matrix/media/r0/thumbnail/${path}?width=64&height=64&method=crop`;
|
|
|
|
|
};
|
|
|
|
|
|
2022-03-07 17:29:36 +00:00
|
|
|
|
export const renderRoomHeader = (room, syncv2ServerUrl) => {
|
|
|
|
|
document.getElementById("selectedroomname").textContent =
|
|
|
|
|
room.name || room.room_id;
|
|
|
|
|
if (room.avatar) {
|
|
|
|
|
document.getElementById("selectedroomavatar").src =
|
|
|
|
|
mxcToUrl(syncv2ServerUrl, room.avatar) || "/client/placeholder.svg";
|
|
|
|
|
} else {
|
|
|
|
|
document.getElementById("selectedroomavatar").src =
|
|
|
|
|
"/client/placeholder.svg";
|
|
|
|
|
}
|
|
|
|
|
if (room.topic) {
|
|
|
|
|
document.getElementById("selectedroomtopic").textContent = room.topic;
|
|
|
|
|
} else {
|
|
|
|
|
document.getElementById("selectedroomtopic").textContent = "";
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-23 12:16:22 +00:00
|
|
|
|
export const renderEvent = (eventIdKey, ev) => {
|
|
|
|
|
const template = document.getElementById("messagetemplate");
|
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#avoiding_documentfragment_pitfall
|
|
|
|
|
const msgCell = template.content.firstElementChild.cloneNode(true);
|
|
|
|
|
msgCell.setAttribute("id", eventIdKey);
|
|
|
|
|
msgCell.getElementsByClassName("msgsender")[0].textContent = ev.sender;
|
2022-02-23 19:26:38 +00:00
|
|
|
|
msgCell.getElementsByClassName("msgtimestamp")[0].textContent =
|
|
|
|
|
formatTimestamp(ev.origin_server_ts);
|
2022-02-23 12:16:22 +00:00
|
|
|
|
let body = textForEvent(ev);
|
|
|
|
|
msgCell.getElementsByClassName("msgcontent")[0].textContent = body;
|
|
|
|
|
return msgCell;
|
2022-02-23 19:26:38 +00:00
|
|
|
|
};
|
2022-02-24 14:43:45 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2022-03-07 17:29:36 +00:00
|
|
|
|
* Render a room cell for the room list.
|
|
|
|
|
* @param {Element} roomCell The DOM element to put the details into. The cell must be already initialised with `roomCellTemplate`.
|
|
|
|
|
* @param {object} room The room data model, which can be null to indicate a placeholder.
|
2022-02-24 14:43:45 +00:00
|
|
|
|
*/
|
2022-03-07 17:29:36 +00:00
|
|
|
|
export const renderRoomCell = (
|
|
|
|
|
roomCell,
|
|
|
|
|
room,
|
|
|
|
|
index,
|
|
|
|
|
isHighlighted,
|
|
|
|
|
syncv2ServerUrl
|
2022-02-24 14:43:45 +00:00
|
|
|
|
) => {
|
2022-03-07 17:29:36 +00:00
|
|
|
|
// if this child is a placeholder and it was previously a placeholder then do nothing.
|
|
|
|
|
if (!room && roomCell.getAttribute("x-placeholder") === "yep") {
|
|
|
|
|
return;
|
2022-02-24 14:43:45 +00:00
|
|
|
|
}
|
2022-03-07 17:29:36 +00:00
|
|
|
|
const roomNameSpan = roomCell.getElementsByClassName("roomname")[0];
|
|
|
|
|
const roomContentSpan = roomCell.getElementsByClassName("roomcontent")[0];
|
|
|
|
|
const roomSenderSpan = roomCell.getElementsByClassName("roomsender")[0];
|
|
|
|
|
const roomTimestampSpan =
|
|
|
|
|
roomCell.getElementsByClassName("roomtimestamp")[0];
|
|
|
|
|
const unreadCountSpan = roomCell.getElementsByClassName("unreadcount")[0];
|
|
|
|
|
|
|
|
|
|
// remove previous unread counts
|
|
|
|
|
unreadCountSpan.textContent = "";
|
|
|
|
|
unreadCountSpan.classList.remove("unreadcountnotify");
|
|
|
|
|
unreadCountSpan.classList.remove("unreadcounthighlight");
|
|
|
|
|
|
|
|
|
|
if (!room) {
|
|
|
|
|
// make a placeholder
|
|
|
|
|
roomNameSpan.textContent = randomName(index, false);
|
|
|
|
|
roomNameSpan.style = "background: #e0e0e0; color: #e0e0e0;";
|
|
|
|
|
roomContentSpan.textContent = randomName(index, true);
|
|
|
|
|
roomContentSpan.style = "background: #e0e0e0; color: #e0e0e0;";
|
|
|
|
|
roomSenderSpan.textContent = "";
|
|
|
|
|
roomTimestampSpan.textContent = "";
|
|
|
|
|
roomCell.getElementsByClassName("roomavatar")[0].src =
|
|
|
|
|
"/client/placeholder.svg";
|
|
|
|
|
roomCell.style = "";
|
|
|
|
|
roomCell.setAttribute("x-placeholder", "yep");
|
|
|
|
|
return;
|
2022-02-24 14:43:45 +00:00
|
|
|
|
}
|
2022-03-07 17:29:36 +00:00
|
|
|
|
|
|
|
|
|
roomCell.removeAttribute("x-placeholder"); // in case this was previously a placeholder
|
|
|
|
|
roomCell.style = "";
|
|
|
|
|
roomNameSpan.textContent = room.name || room.room_id;
|
|
|
|
|
roomNameSpan.style = "";
|
|
|
|
|
roomContentSpan.style = "";
|
|
|
|
|
if (room.avatar) {
|
|
|
|
|
roomCell.getElementsByClassName("roomavatar")[0].src =
|
|
|
|
|
mxcToUrl(syncv2ServerUrl, room.avatar) || "/client/placeholder.svg";
|
|
|
|
|
} else {
|
|
|
|
|
roomCell.getElementsByClassName("roomavatar")[0].src =
|
|
|
|
|
"/client/placeholder.svg";
|
2022-02-24 14:43:45 +00:00
|
|
|
|
}
|
2022-03-07 17:29:36 +00:00
|
|
|
|
if (isHighlighted) {
|
|
|
|
|
roomCell.style = "background: #d7d7f7";
|
|
|
|
|
}
|
|
|
|
|
if (room.highlight_count > 0) {
|
|
|
|
|
// use the notification count instead to avoid counts dropping down. This matches ele-web
|
|
|
|
|
unreadCountSpan.textContent = room.notification_count + "";
|
|
|
|
|
unreadCountSpan.classList.add("unreadcounthighlight");
|
|
|
|
|
} else if (room.notification_count > 0) {
|
|
|
|
|
unreadCountSpan.textContent = room.notification_count + "";
|
|
|
|
|
unreadCountSpan.classList.add("unreadcountnotify");
|
|
|
|
|
} else {
|
2022-02-24 14:43:45 +00:00
|
|
|
|
unreadCountSpan.textContent = "";
|
2022-03-07 17:29:36 +00:00
|
|
|
|
}
|
2022-02-24 14:43:45 +00:00
|
|
|
|
|
2022-03-07 17:29:36 +00:00
|
|
|
|
if (room.obsolete) {
|
|
|
|
|
roomContentSpan.textContent = "";
|
|
|
|
|
roomSenderSpan.textContent = room.obsolete;
|
|
|
|
|
} else if (room.timeline && room.timeline.length > 0) {
|
|
|
|
|
const mostRecentEvent = room.timeline[room.timeline.length - 1];
|
|
|
|
|
roomSenderSpan.textContent = mostRecentEvent.sender;
|
2022-02-24 14:43:45 +00:00
|
|
|
|
|
2022-03-07 17:29:36 +00:00
|
|
|
|
roomTimestampSpan.textContent = formatTimestamp(
|
|
|
|
|
mostRecentEvent.origin_server_ts
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const body = textForEvent(mostRecentEvent);
|
|
|
|
|
if (mostRecentEvent.type === "m.room.member") {
|
2022-02-24 14:43:45 +00:00
|
|
|
|
roomContentSpan.textContent = "";
|
2022-03-07 17:29:36 +00:00
|
|
|
|
roomSenderSpan.textContent = body;
|
|
|
|
|
} else {
|
|
|
|
|
roomContentSpan.textContent = body;
|
2022-02-24 14:43:45 +00:00
|
|
|
|
}
|
2022-03-07 17:29:36 +00:00
|
|
|
|
} else {
|
|
|
|
|
roomContentSpan.textContent = "";
|
2022-02-24 14:43:45 +00:00
|
|
|
|
}
|
|
|
|
|
};
|