remove depracated code & fix attachment name handling

This commit is contained in:
olcxja 2026-07-24 23:04:57 +02:00
commit 91d293ee05
4 changed files with 64 additions and 26 deletions

View file

@ -1597,7 +1597,17 @@ async function openProfile(accountId) {
let bannerUrl = `${url}/user/storage/public/getentry?id=${accountId}&e=larp.profile.banner`;
if (accountId === window.id && window.profileUpdateTimestamp) bannerUrl += `&t=${window.profileUpdateTimestamp}`;
let bannerHtml = `<img src="${bannerUrl}" class="profile-banner" onerror="this.outerHTML='<div class=\\'profile-banner\\'></div>'">`;
let bannerHtml = `<img src="${bannerUrl}" class="profile-banner">`;
setTimeout(() => {
let bannerImg = document.querySelector("#profile-popup-inner .profile-banner");
if (bannerImg) {
bannerImg.addEventListener("error", function() {
let div = document.createElement("div");
div.className = "profile-banner";
this.parentNode.replaceChild(div, this);
});
}
}, 50);
let bio = await fetchAsync(`${url}/user/storage/public/getentry?id=${accountId}&e=larp.profile.bio`);
if (bio.startsWith("error:")) bio = "";
@ -1639,7 +1649,8 @@ async function openProfile(accountId) {
}
if (hasDm) {
actionBtnHtml = `<button class="profile-action-btn" onclick="openDm('${dmRoomId}', '${nameWithHost}', '${accountId}'); closeProfile();">${processBlah('action.open.dm')}</button>`;
let safeName = encodeURIComponent(nameWithHost).replace(/'/g, "%27");
actionBtnHtml = `<button class="profile-action-btn" onclick="openDm('${dmRoomId}', decodeURIComponent('${safeName}'), '${accountId}'); closeProfile();">${processBlah('action.open.dm')}</button>`;
} else {
let sentInvite = false;
let receivedInvite = false;
@ -2156,8 +2167,10 @@ async function renderDms(res) {
let isRead = dmData.string3 === "true";
let nameStyle = isRead ? "opacity: 0.8;" : "opacity: 1;";
let safeTargetUsername = encodeURIComponent(targetUsername).replace(/'/g, "%27");
html += `
<button class="room-entry" id="dm-btn-${dmId}" onclick="openDm('${dmId}', '${targetUsername}', '${targetId}')">
<button class="room-entry" id="dm-btn-${dmId}" onclick="openDm('${dmId}', decodeURIComponent('${safeTargetUsername}'), '${targetId}')">
<img src="${pfp}" class="room-pfp">
<div style="display: flex; flex-direction: column; text-align: left; overflow: hidden; width: 100%; margin-left: 0.37rem;">
<span class="room-name" style="${nameStyle}">${displayName}</span>
@ -2403,7 +2416,10 @@ async function renderMessages(messages, isPrepend = false) {
? `${ICONS.image({ width: "1.5rem", height: "1.5rem", stroke: "currentColor" })}`
: `${ICONS.download({ width: "1.5rem", height: "1.5rem", stroke: "currentColor" })}`;
attachmentsHtml += `<div id="${attContainerId}" class="attachment-box" style="position: relative; min-width: 120px; max-width: 300px; min-height: 100px; max-height: 300px; background: rgba(0,0,0,0.2); border: 1px solid var(--border-color); border-radius: 8px; display: flex; align-items: center; justify-content: center; cursor: pointer; overflow: hidden;" onclick="downloadAndRenderAttachment('${msgId}', '${att.id}', '${escapeHtml(att.type)}', '${escapeHtml(att.name)}')">
let safeType = encodeURIComponent(att.type).replace(/'/g, "%27");
let safeName = encodeURIComponent(att.name).replace(/'/g, "%27");
attachmentsHtml += `<div id="${attContainerId}" class="attachment-box" style="position: relative; min-width: 120px; max-width: 300px; min-height: 100px; max-height: 300px; background: rgba(0,0,0,0.2); border: 1px solid var(--border-color); border-radius: 8px; display: flex; align-items: center; justify-content: center; cursor: pointer; overflow: hidden;" onclick="downloadAndRenderAttachment('${msgId}', '${att.id}', decodeURIComponent('${safeType}'), decodeURIComponent('${safeName}'))">
<div style="padding: 1rem; text-align: center; color: var(--text-color);">
${iconSvg}
<div style="font-size: 0.8rem; margin-top: 0.5rem; word-break: break-all;">${escapeHtml(displayName)}</div>
@ -2589,7 +2605,7 @@ async function renderMessages(messages, isPrepend = false) {
html += `
<div class="chat-message ${extraClass}" data-msg-id="${msgId}" id="msg-${msgId}">
${showAvatar ? `<img src="${pfp}" class="chat-message-pfp" onclick="openProfile('${msg.author}')" style="cursor: pointer;">` : `<div style="width: 2.5rem; flex-shrink: 0;"></div>`}
<div class="chat-message-content" oncontextmenu="handleMessageContextMenu(event, '${msgId}')">
<div class="chat-message-content" oncontextmenu="handleMessageContextMenu(arguments[0], '${msgId}')">
${showAvatar ? `<div class="chat-message-header">
<span class="chat-message-author" onclick="openProfile('${msg.author}')" style="cursor: pointer;">${authorName}</span>
<span class="chat-message-timestamp">${timeStr}</span>
@ -3261,9 +3277,12 @@ async function loadEmotes() {
reactionPickerMenuHtml = `
<div style="display: flex; flex-direction: column; gap: 0.4rem; padding: 0.2rem; min-width: 14rem;">
<input type="text" id="reaction-picker-search" placeholder="{blah(placeholder.type.text.emoji)}" oninput="filterReactions(this.value)" onkeydown="if(event.key === 'Enter') { if(this.value.trim() !== '') reactMessagePrompt(currentContextMenuMsgId, encodeURIComponent(this.value)); }" style="width: auto; align-self: stretch; margin: 0; box-sizing: border-box; padding: 0.5rem 0.6rem; border-radius: 0.65rem; border: var(--border-width) solid var(--light-border-color); background: transparent; color: var(--text-color); font-family: inherit;">
<input type="text" id="reaction-picker-search" placeholder="{blah(placeholder.type.text.emoji)}" oninput="filterReactions(this.value)" onkeydown="if(arguments[0].key === 'Enter') { if(this.value.trim() !== '') reactMessagePrompt(currentContextMenuMsgId, encodeURIComponent(this.value)); }" style="width: auto; align-self: stretch; margin: 0; box-sizing: border-box; padding: 0.5rem 0.6rem; border-radius: 0.65rem; border: var(--border-width) solid var(--light-border-color); background: transparent; color: var(--text-color); font-family: inherit;">
<div id="reaction-picker-grid" style="display: grid; grid-template-columns: repeat(5, 1fr); gap: 0.2rem; max-height: 12rem; overflow-y: auto; overflow-x: hidden;">
${loadedEmotes.map(emoji => `<button onclick="reactMessagePrompt(currentContextMenuMsgId, encodeURIComponent('${emoji.char}'))" data-name="${emoji.name}" style="min-width: unset; width: 100%; aspect-ratio: 1; display: flex; justify-content: center; align-items: center; padding: 0; font-size: 1.2rem; border-radius: 0.65rem;" class="reaction-emoji-btn">${emoji.char}</button>`).join('')}
${loadedEmotes.map(emoji => {
let safeChar = encodeURIComponent(emoji.char).replace(/'/g, "%27");
return `<button onclick="reactMessagePrompt(currentContextMenuMsgId, '${safeChar}')" data-name="${emoji.name}" style="min-width: unset; width: 100%; aspect-ratio: 1; display: flex; justify-content: center; align-items: center; padding: 0; font-size: 1.2rem; border-radius: 0.65rem;" class="reaction-emoji-btn">${emoji.char}</button>`;
}).join('')}
</div>
<button class="reaction-text-btn" onclick="reactMessagePrompt(currentContextMenuMsgId, encodeURIComponent(document.getElementById('reaction-picker-search').value))" style="margin: 0; padding: 0.5rem; justify-content: center; border-radius: 0.65rem; width: 100%;">
<span class="blah">title.text.react</span>

View file

@ -143,10 +143,10 @@ var chatScreen = `
</div>
<div id="attachments-preview" style="display: none; padding: 0.5rem 1rem; gap: 0.8rem; overflow-x: auto; border-top: var(--border-width) solid var(--light-border-color); background: var(--main-bg-color); align-items: center; flex-shrink: 0;"></div>
<div style="padding: 1rem; border-top: var(--border-width) solid var(--light-border-color); display: flex; gap: 0.5rem; align-items: flex-end; flex-shrink: 0;">
<button id="chat-add-attachment" class="submit-button" onclick="clickAddAttachment(this, event)" style="margin: 0; padding: 0; width: 2.5rem; flex-shrink: 0; min-height: 2.5rem; max-height: 8rem;">
<button id="chat-add-attachment" class="submit-button" onclick="clickAddAttachment(this, arguments[0])" style="margin: 0; padding: 0; width: 2.5rem; flex-shrink: 0; min-height: 2.5rem; max-height: 8rem;">
${ICONS.plus({ width: "1.5rem", height: "1.5rem", stroke: "var(--main-bg-color)" })}
</button>
<textarea id="chat-input" class="forminput" style="flex-grow: 1; margin: 0; resize: none; min-height: 2.5rem; max-height: 8rem; padding: 0.5rem;" placeholder="{blah(placeholder.message.input)}" onkeydown="handleChatInputKey(event)" oninput="handleChatInputResize(this)"></textarea>
<textarea id="chat-input" class="forminput" style="flex-grow: 1; margin: 0; resize: none; min-height: 2.5rem; max-height: 8rem; padding: 0.5rem;" placeholder="{blah(placeholder.message.input)}" onkeydown="handleChatInputKey(arguments[0])" oninput="handleChatInputResize(this)"></textarea>
<button id="chat-sendmessage" class="submit-button" onclick="sendMessage(this)" style="margin: 0; padding: 0; width: 2.5rem; flex-shrink: 0; min-height: 2.5rem; max-height: 8rem;">
${ICONS.send()}
</button>
@ -236,9 +236,9 @@ var attachmentMenu = `
${ICONS.poll()}
<span class="blah">action.attachment.poll</span>
</button>
<input type="file" id="attach-take-photo" accept="image/*" capture="environment" style="display: none;" onchange="handleAttachmentSelection(event)" multiple>
<input type="file" id="attach-media" accept="image/*,video/*" style="display: none;" onchange="handleAttachmentSelection(event)" multiple>
<input type="file" id="attach-file" style="display: none;" onchange="handleAttachmentSelection(event)" multiple>
<input type="file" id="attach-take-photo" accept="image/*" capture="environment" style="display: none;" onchange="handleAttachmentSelection(arguments[0])" multiple>
<input type="file" id="attach-media" accept="image/*,video/*" style="display: none;" onchange="handleAttachmentSelection(arguments[0])" multiple>
<input type="file" id="attach-file" style="display: none;" onchange="handleAttachmentSelection(arguments[0])" multiple>
`;
var addSpaceMenu = `
@ -255,7 +255,7 @@ var messageContextMenu = `
${ICONS.replyAction()}
<span class="blah">title.reply.message</span>
</button>
<button id="context-react-btn" onclick="openReactionPicker(event)">
<button id="context-react-btn" onclick="openReactionPicker(arguments[0])">
${ICONS.react()}
<span class="blah">title.react.message</span>
</button>

View file

@ -1597,7 +1597,17 @@ async function openProfile(accountId) {
let bannerUrl = `${url}/user/storage/public/getentry?id=${accountId}&e=larp.profile.banner`;
if (accountId === window.id && window.profileUpdateTimestamp) bannerUrl += `&t=${window.profileUpdateTimestamp}`;
let bannerHtml = `<img src="${bannerUrl}" class="profile-banner" onerror="this.outerHTML='<div class=\\'profile-banner\\'></div>'">`;
let bannerHtml = `<img src="${bannerUrl}" class="profile-banner">`;
setTimeout(() => {
let bannerImg = document.querySelector("#profile-popup-inner .profile-banner");
if (bannerImg) {
bannerImg.addEventListener("error", function() {
let div = document.createElement("div");
div.className = "profile-banner";
this.parentNode.replaceChild(div, this);
});
}
}, 50);
let bio = await fetchAsync(`${url}/user/storage/public/getentry?id=${accountId}&e=larp.profile.bio`);
if (bio.startsWith("error:")) bio = "";
@ -1639,7 +1649,8 @@ async function openProfile(accountId) {
}
if (hasDm) {
actionBtnHtml = `<button class="profile-action-btn" onclick="openDm('${dmRoomId}', '${nameWithHost}', '${accountId}'); closeProfile();">${processBlah('action.open.dm')}</button>`;
let safeName = encodeURIComponent(nameWithHost).replace(/'/g, "%27");
actionBtnHtml = `<button class="profile-action-btn" onclick="openDm('${dmRoomId}', decodeURIComponent('${safeName}'), '${accountId}'); closeProfile();">${processBlah('action.open.dm')}</button>`;
} else {
let sentInvite = false;
let receivedInvite = false;
@ -2156,8 +2167,10 @@ async function renderDms(res) {
let isRead = dmData.string3 === "true";
let nameStyle = isRead ? "opacity: 0.8;" : "opacity: 1;";
let safeTargetUsername = encodeURIComponent(targetUsername).replace(/'/g, "%27");
html += `
<button class="room-entry" id="dm-btn-${dmId}" onclick="openDm('${dmId}', '${targetUsername}', '${targetId}')">
<button class="room-entry" id="dm-btn-${dmId}" onclick="openDm('${dmId}', decodeURIComponent('${safeTargetUsername}'), '${targetId}')">
<img src="${pfp}" class="room-pfp">
<div style="display: flex; flex-direction: column; text-align: left; overflow: hidden; width: 100%; margin-left: 0.37rem;">
<span class="room-name" style="${nameStyle}">${displayName}</span>
@ -2403,7 +2416,10 @@ async function renderMessages(messages, isPrepend = false) {
? `${ICONS.image({ width: "1.5rem", height: "1.5rem", stroke: "currentColor" })}`
: `${ICONS.download({ width: "1.5rem", height: "1.5rem", stroke: "currentColor" })}`;
attachmentsHtml += `<div id="${attContainerId}" class="attachment-box" style="position: relative; min-width: 120px; max-width: 300px; min-height: 100px; max-height: 300px; background: rgba(0,0,0,0.2); border: 1px solid var(--border-color); border-radius: 8px; display: flex; align-items: center; justify-content: center; cursor: pointer; overflow: hidden;" onclick="downloadAndRenderAttachment('${msgId}', '${att.id}', '${escapeHtml(att.type)}', '${escapeHtml(att.name)}')">
let safeType = encodeURIComponent(att.type).replace(/'/g, "%27");
let safeName = encodeURIComponent(att.name).replace(/'/g, "%27");
attachmentsHtml += `<div id="${attContainerId}" class="attachment-box" style="position: relative; min-width: 120px; max-width: 300px; min-height: 100px; max-height: 300px; background: rgba(0,0,0,0.2); border: 1px solid var(--border-color); border-radius: 8px; display: flex; align-items: center; justify-content: center; cursor: pointer; overflow: hidden;" onclick="downloadAndRenderAttachment('${msgId}', '${att.id}', decodeURIComponent('${safeType}'), decodeURIComponent('${safeName}'))">
<div style="padding: 1rem; text-align: center; color: var(--text-color);">
${iconSvg}
<div style="font-size: 0.8rem; margin-top: 0.5rem; word-break: break-all;">${escapeHtml(displayName)}</div>
@ -2589,7 +2605,7 @@ async function renderMessages(messages, isPrepend = false) {
html += `
<div class="chat-message ${extraClass}" data-msg-id="${msgId}" id="msg-${msgId}">
${showAvatar ? `<img src="${pfp}" class="chat-message-pfp" onclick="openProfile('${msg.author}')" style="cursor: pointer;">` : `<div style="width: 2.5rem; flex-shrink: 0;"></div>`}
<div class="chat-message-content" oncontextmenu="handleMessageContextMenu(event, '${msgId}')">
<div class="chat-message-content" oncontextmenu="handleMessageContextMenu(arguments[0], '${msgId}')">
${showAvatar ? `<div class="chat-message-header">
<span class="chat-message-author" onclick="openProfile('${msg.author}')" style="cursor: pointer;">${authorName}</span>
<span class="chat-message-timestamp">${timeStr}</span>
@ -3261,9 +3277,12 @@ async function loadEmotes() {
reactionPickerMenuHtml = `
<div style="display: flex; flex-direction: column; gap: 0.4rem; padding: 0.2rem; min-width: 14rem;">
<input type="text" id="reaction-picker-search" placeholder="{blah(placeholder.type.text.emoji)}" oninput="filterReactions(this.value)" onkeydown="if(event.key === 'Enter') { if(this.value.trim() !== '') reactMessagePrompt(currentContextMenuMsgId, encodeURIComponent(this.value)); }" style="width: auto; align-self: stretch; margin: 0; box-sizing: border-box; padding: 0.5rem 0.6rem; border-radius: 0.65rem; border: var(--border-width) solid var(--light-border-color); background: transparent; color: var(--text-color); font-family: inherit;">
<input type="text" id="reaction-picker-search" placeholder="{blah(placeholder.type.text.emoji)}" oninput="filterReactions(this.value)" onkeydown="if(arguments[0].key === 'Enter') { if(this.value.trim() !== '') reactMessagePrompt(currentContextMenuMsgId, encodeURIComponent(this.value)); }" style="width: auto; align-self: stretch; margin: 0; box-sizing: border-box; padding: 0.5rem 0.6rem; border-radius: 0.65rem; border: var(--border-width) solid var(--light-border-color); background: transparent; color: var(--text-color); font-family: inherit;">
<div id="reaction-picker-grid" style="display: grid; grid-template-columns: repeat(5, 1fr); gap: 0.2rem; max-height: 12rem; overflow-y: auto; overflow-x: hidden;">
${loadedEmotes.map(emoji => `<button onclick="reactMessagePrompt(currentContextMenuMsgId, encodeURIComponent('${emoji.char}'))" data-name="${emoji.name}" style="min-width: unset; width: 100%; aspect-ratio: 1; display: flex; justify-content: center; align-items: center; padding: 0; font-size: 1.2rem; border-radius: 0.65rem;" class="reaction-emoji-btn">${emoji.char}</button>`).join('')}
${loadedEmotes.map(emoji => {
let safeChar = encodeURIComponent(emoji.char).replace(/'/g, "%27");
return `<button onclick="reactMessagePrompt(currentContextMenuMsgId, '${safeChar}')" data-name="${emoji.name}" style="min-width: unset; width: 100%; aspect-ratio: 1; display: flex; justify-content: center; align-items: center; padding: 0; font-size: 1.2rem; border-radius: 0.65rem;" class="reaction-emoji-btn">${emoji.char}</button>`;
}).join('')}
</div>
<button class="reaction-text-btn" onclick="reactMessagePrompt(currentContextMenuMsgId, encodeURIComponent(document.getElementById('reaction-picker-search').value))" style="margin: 0; padding: 0.5rem; justify-content: center; border-radius: 0.65rem; width: 100%;">
<span class="blah">title.text.react</span>

View file

@ -143,10 +143,10 @@ var chatScreen = `
</div>
<div id="attachments-preview" style="display: none; padding: 0.5rem 1rem; gap: 0.8rem; overflow-x: auto; border-top: var(--border-width) solid var(--light-border-color); background: var(--main-bg-color); align-items: center; flex-shrink: 0;"></div>
<div style="padding: 1rem; border-top: var(--border-width) solid var(--light-border-color); display: flex; gap: 0.5rem; align-items: flex-end; flex-shrink: 0;">
<button id="chat-add-attachment" class="submit-button" onclick="clickAddAttachment(this, event)" style="margin: 0; padding: 0; width: 2.5rem; flex-shrink: 0; min-height: 2.5rem; max-height: 8rem;">
<button id="chat-add-attachment" class="submit-button" onclick="clickAddAttachment(this, arguments[0])" style="margin: 0; padding: 0; width: 2.5rem; flex-shrink: 0; min-height: 2.5rem; max-height: 8rem;">
${ICONS.plus({ width: "1.5rem", height: "1.5rem", stroke: "var(--main-bg-color)" })}
</button>
<textarea id="chat-input" class="forminput" style="flex-grow: 1; margin: 0; resize: none; min-height: 2.5rem; max-height: 8rem; padding: 0.5rem;" placeholder="{blah(placeholder.message.input)}" onkeydown="handleChatInputKey(event)" oninput="handleChatInputResize(this)"></textarea>
<textarea id="chat-input" class="forminput" style="flex-grow: 1; margin: 0; resize: none; min-height: 2.5rem; max-height: 8rem; padding: 0.5rem;" placeholder="{blah(placeholder.message.input)}" onkeydown="handleChatInputKey(arguments[0])" oninput="handleChatInputResize(this)"></textarea>
<button id="chat-sendmessage" class="submit-button" onclick="sendMessage(this)" style="margin: 0; padding: 0; width: 2.5rem; flex-shrink: 0; min-height: 2.5rem; max-height: 8rem;">
${ICONS.send()}
</button>
@ -236,9 +236,9 @@ var attachmentMenu = `
${ICONS.poll()}
<span class="blah">action.attachment.poll</span>
</button>
<input type="file" id="attach-take-photo" accept="image/*" capture="environment" style="display: none;" onchange="handleAttachmentSelection(event)" multiple>
<input type="file" id="attach-media" accept="image/*,video/*" style="display: none;" onchange="handleAttachmentSelection(event)" multiple>
<input type="file" id="attach-file" style="display: none;" onchange="handleAttachmentSelection(event)" multiple>
<input type="file" id="attach-take-photo" accept="image/*" capture="environment" style="display: none;" onchange="handleAttachmentSelection(arguments[0])" multiple>
<input type="file" id="attach-media" accept="image/*,video/*" style="display: none;" onchange="handleAttachmentSelection(arguments[0])" multiple>
<input type="file" id="attach-file" style="display: none;" onchange="handleAttachmentSelection(arguments[0])" multiple>
`;
var addSpaceMenu = `
@ -255,7 +255,7 @@ var messageContextMenu = `
${ICONS.replyAction()}
<span class="blah">title.reply.message</span>
</button>
<button id="context-react-btn" onclick="openReactionPicker(event)">
<button id="context-react-btn" onclick="openReactionPicker(arguments[0])">
${ICONS.react()}
<span class="blah">title.react.message</span>
</button>