g
All checks were successful
/ upload (release) Successful in 22s

This commit is contained in:
pavel 2026-02-24 23:39:27 +01:00
commit 92cba49b0d
6 changed files with 472 additions and 108 deletions

View file

@ -132,6 +132,13 @@ const el = {
mobileMembersBtn: document.getElementById("mobile-members-btn"),
overlay: document.getElementById("overlay"),
utilitySidebar: document.getElementById("utility-sidebar"),
// GIF Picker
gifBtn: document.getElementById("gif-btn"),
gifPicker: document.getElementById("gif-picker"),
gifPickerClose: document.getElementById("gif-picker-close"),
gifSearchInput: document.getElementById("gif-search-input"),
gifResults: document.getElementById("gif-results"),
};
// --- API Helpers ---
@ -222,6 +229,18 @@ function escapeHtml(s) {
.replaceAll("'", "'");
}
function formatMessageBody(body) {
const escaped = escapeHtml(body);
// Detect GIF URLs (simple regex for demo)
const urlRegex = /(https?:\/\/[^\s]+(?:\.gif|\/giphy\.gif)[^\s]*)/gi;
if (urlRegex.test(body)) {
return escaped.replace(urlRegex, (url) => {
return `<div class="msg-gif"><img src="${url}" loading="lazy" /></div>`;
});
}
return escaped;
}
function formatDate(isoString) {
const d = new Date(isoString);
const now = new Date();
@ -423,7 +442,7 @@ function renderMessages(messages) {
const displayName = m.author_display_name || "Unknown User";
if (isGrouped) {
row.innerHTML = `<div class="msg-content"><div class="msg-body">${escapeHtml(m.body)}</div></div>`;
row.innerHTML = `<div class="msg-content"><div class="msg-body">${formatMessageBody(m.body)}</div></div>`;
} else {
row.innerHTML = `
<div class="msg-avatar">${shortName(displayName)}</div>
@ -432,7 +451,7 @@ function renderMessages(messages) {
<span class="msg-author">${escapeHtml(displayName)}</span>
<span class="msg-time">${formatDate(m.created_at)}</span>
</div>
<div class="msg-body">${escapeHtml(m.body)}</div>
<div class="msg-body">${formatMessageBody(m.body)}</div>
</div>
`;
}
@ -1435,6 +1454,84 @@ async function init() {
}
};
// --- GIF Picker Logic ---
const GIPHY_API_KEY = "dc6zaTOxFJmzC"; // Public beta key
el.gifBtn.onclick = () => {
el.gifPicker.classList.remove("hidden");
searchGifs(""); // Initial trending search
};
el.gifPickerClose.onclick = () => {
el.gifPicker.classList.add("hidden");
};
let searchTimeout = null;
el.gifSearchInput.oninput = () => {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
searchGifs(el.gifSearchInput.value);
}, 500);
};
async function searchGifs(query) {
el.gifResults.innerHTML = '<div class="gif-loading">Searching...</div>';
const endpoint = query
? `https://api.giphy.com/v1/gifs/search?api_key=${GIPHY_API_KEY}&q=${encodeURIComponent(query)}&limit=20`
: `https://api.giphy.com/v1/gifs/trending?api_key=${GIPHY_API_KEY}&limit=20`;
try {
const res = await fetch(endpoint);
const data = await res.json();
renderGifs(data.data);
} catch (err) {
el.gifResults.innerHTML = '<div class="gif-loading">Error loading GIFs</div>';
}
}
function renderGifs(gifs) {
el.gifResults.innerHTML = "";
if (!gifs || gifs.length === 0) {
el.gifResults.innerHTML = '<div class="gif-loading">No GIFs found</div>';
return;
}
gifs.forEach(gif => {
const imgUrl = gif.images.fixed_height.url;
const item = document.createElement("div");
item.className = "gif-item";
item.innerHTML = `<img src="${imgUrl}" loading="lazy" />`;
item.onclick = () => {
sendGif(imgUrl);
el.gifPicker.classList.add("hidden");
el.gifSearchInput.value = "";
};
el.gifResults.appendChild(item);
});
}
async function sendGif(url) {
try {
if (state.selectedTextChannelId) {
await api(`/channels/${state.selectedTextChannelId}/messages`, {
method: "POST",
body: JSON.stringify({ body: url }),
});
} else if (state.selectedDmUserId) {
await api(`/dms/${state.selectedDmUserId}/messages`, {
method: "POST",
body: JSON.stringify({ body: url }),
});
}
const messages = state.selectedTextChannelId
? await api(`/channels/${state.selectedTextChannelId}/messages?limit=100`)
: await api(`/dms/${state.selectedDmUserId}/messages?limit=100`);
renderMessages(messages);
} catch (err) {
console.error("Failed to send GIF", err);
}
}
try {
state.me = await api("/me");
if (state.me && state.me.display_name) {