profile update
This commit is contained in:
@@ -6140,6 +6140,7 @@ video.emoji {
|
|||||||
height: auto;
|
height: auto;
|
||||||
/* vertical-align: middle; */
|
/* vertical-align: middle; */
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
max-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* video in emoji autocomplete dropdown */
|
/* video in emoji autocomplete dropdown */
|
||||||
|
|||||||
@@ -7343,11 +7343,20 @@ class NotificationSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (data.type === 'profile_update') {
|
} else if (data.type === 'profile_update') {
|
||||||
const { display_name, user, banner_file, banner_position, banner_size } = data.data;
|
const { display_name, user, banner_file, banner_position, banner_size, avatar_file, username_color, description } = data.data;
|
||||||
if (display_name !== undefined) this.applyDisplayNameUpdate(display_name, user);
|
if (display_name !== undefined) this.applyDisplayNameUpdate(display_name, user);
|
||||||
if (banner_file !== undefined || banner_position !== undefined || banner_size !== undefined) {
|
if (banner_file !== undefined || banner_position !== undefined || banner_size !== undefined) {
|
||||||
this.applyBannerUpdate(banner_file, banner_position, banner_size, user);
|
this.applyBannerUpdate(banner_file, banner_position, banner_size, user);
|
||||||
}
|
}
|
||||||
|
if (avatar_file !== undefined) {
|
||||||
|
this.applyAvatarUpdate(avatar_file, user);
|
||||||
|
}
|
||||||
|
if (username_color !== undefined) {
|
||||||
|
this.applyUsernameColorUpdate(username_color, user);
|
||||||
|
}
|
||||||
|
if (description !== undefined) {
|
||||||
|
this.applyDescriptionUpdate(description, user);
|
||||||
|
}
|
||||||
// Sync preferences to global session object for client-side gating (like DND)
|
// Sync preferences to global session object for client-side gating (like DND)
|
||||||
if (window.f0ckSession && data.data.user_id === window.f0ckSession.id) {
|
if (window.f0ckSession && data.data.user_id === window.f0ckSession.id) {
|
||||||
for (const key in data.data) {
|
for (const key in data.data) {
|
||||||
@@ -7377,14 +7386,28 @@ class NotificationSystem {
|
|||||||
// Capture old value before overwriting — needed for thumb matching below
|
// Capture old value before overwriting — needed for thumb matching below
|
||||||
const oldDisplayName = window.f0ckSession?.display_name || null;
|
const oldDisplayName = window.f0ckSession?.display_name || null;
|
||||||
if (window.f0ckSession) window.f0ckSession.display_name = display_name || null;
|
if (window.f0ckSession) window.f0ckSession.display_name = display_name || null;
|
||||||
const navBtn = document.getElementById('nav-user-toggle');
|
|
||||||
if (navBtn) {
|
|
||||||
const nameSpan = document.getElementById('nav-display-name');
|
|
||||||
if (nameSpan) {
|
|
||||||
nameSpan.textContent = display_name || window.f0ckSession?.user || '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const userName = user || window.f0ckSession?.user;
|
const userName = user || window.f0ckSession?.user;
|
||||||
|
|
||||||
|
// Update ALL nav-display-name instances (handles the profile page having a duplicate ID)
|
||||||
|
document.querySelectorAll('#nav-display-name').forEach(nameSpan => {
|
||||||
|
// preserve the badges (Admin, Mod)
|
||||||
|
for (let i = nameSpan.childNodes.length - 1; i >= 0; i--) {
|
||||||
|
let node = nameSpan.childNodes[i];
|
||||||
|
if (node.nodeType === Node.TEXT_NODE && node.nodeValue.trim().length > 0) {
|
||||||
|
// Match and preserve any non-breaking spaces at the start (from admin/mod badges)
|
||||||
|
const match = node.nodeValue.match(new RegExp('^(\\s*)(.*)'));
|
||||||
|
node.nodeValue = (match ? match[1] : '') + (display_name || userName || '');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const bracket = document.getElementById('username-bracket');
|
||||||
|
if (bracket) {
|
||||||
|
bracket.style.display = display_name ? 'inline' : 'none';
|
||||||
|
}
|
||||||
|
|
||||||
if (userName) {
|
if (userName) {
|
||||||
const userHref = `/user/${userName}`;
|
const userHref = `/user/${userName}`;
|
||||||
// Sidebar / thread comment author links
|
// Sidebar / thread comment author links
|
||||||
@@ -7406,6 +7429,105 @@ class NotificationSystem {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Helper: apply a username color change to relevant DOM nodes
|
||||||
|
this.applyUsernameColorUpdate = (username_color, user) => {
|
||||||
|
const userName = user || window.f0ckSession?.user;
|
||||||
|
if (!userName) return;
|
||||||
|
|
||||||
|
const userHref = `/user/${userName}`;
|
||||||
|
document.querySelectorAll(`a.comment-author[href="${userHref}"]`).forEach(el => {
|
||||||
|
if (username_color) {
|
||||||
|
el.style.color = username_color;
|
||||||
|
} else {
|
||||||
|
el.style.removeProperty('color');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle the item view username link
|
||||||
|
const aUsername = document.getElementById('a_username');
|
||||||
|
if (aUsername && aUsername.getAttribute('href') === userHref) {
|
||||||
|
if (username_color) {
|
||||||
|
aUsername.style.color = username_color;
|
||||||
|
} else {
|
||||||
|
aUsername.style.removeProperty('color');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle favs avatar border color
|
||||||
|
document.querySelectorAll('#favs img').forEach(img => {
|
||||||
|
const link = img.closest('a');
|
||||||
|
if (link && (link.href.includes(`/user/${userName.toLowerCase()}`) || link.href.includes(`/user/${userName}`))) {
|
||||||
|
if (username_color) {
|
||||||
|
img.style.borderColor = username_color;
|
||||||
|
} else {
|
||||||
|
img.style.removeProperty('border-color');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the infobox block variables for color accents
|
||||||
|
const safeUserName = userName.replace(/"/g, '\\"');
|
||||||
|
document.querySelectorAll(`.user-infobox-block[data-banner-user="${safeUserName}"]`).forEach(block => {
|
||||||
|
if (username_color) {
|
||||||
|
block.style.setProperty('--author-accent', username_color);
|
||||||
|
block.style.setProperty('--author-border', username_color);
|
||||||
|
} else {
|
||||||
|
block.style.setProperty('--author-accent', 'var(--accent)');
|
||||||
|
block.style.setProperty('--author-border', 'var(--accent)');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Special case for settings page preview block
|
||||||
|
if (window.f0ckSession && userName === window.f0ckSession.user) {
|
||||||
|
const previewBlock = document.getElementById('live-profile-preview-box');
|
||||||
|
if (previewBlock) {
|
||||||
|
if (username_color) {
|
||||||
|
previewBlock.style.setProperty('--author-accent', username_color);
|
||||||
|
previewBlock.style.setProperty('--author-border', username_color);
|
||||||
|
} else {
|
||||||
|
previewBlock.style.setProperty('--author-accent', 'var(--accent)');
|
||||||
|
previewBlock.style.setProperty('--author-border', 'var(--accent)');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the nav-display-name span elements (profile header and top navbar)
|
||||||
|
if (window.f0ckSession && userName === window.f0ckSession.user) {
|
||||||
|
document.querySelectorAll('#nav-display-name').forEach(el => {
|
||||||
|
if (username_color) {
|
||||||
|
el.style.color = username_color;
|
||||||
|
} else {
|
||||||
|
el.style.removeProperty('color');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper: apply an avatar update to relevant DOM nodes
|
||||||
|
this.applyAvatarUpdate = (avatar_file, user) => {
|
||||||
|
const userName = user || window.f0ckSession?.user;
|
||||||
|
if (!userName) return;
|
||||||
|
|
||||||
|
const newSrc = avatar_file ? `/a/${avatar_file}?t=${Date.now()}` : '/a/default.png';
|
||||||
|
|
||||||
|
// Update Nav Avatar & profile header Avatar (only for current user)
|
||||||
|
if (window.f0ckSession && userName === window.f0ckSession.user) {
|
||||||
|
document.querySelectorAll('.nav-avatar-img, .profile_head_avatar img').forEach(img => img.src = newSrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update globally (comments, sidebar, polls, rank, infoboxes, favs)
|
||||||
|
// We broadly target a[href^="/user/"] img to catch basically any avatar linked to the profile
|
||||||
|
const lowerHref = `/user/${userName.toLowerCase()}`;
|
||||||
|
const exactHref = `/user/${userName}`;
|
||||||
|
|
||||||
|
document.querySelectorAll('.comment-avatar img, .sidebar-avatar, .poll-voter-avatar, .rank-avatar, .user-infobox-avatar img, #favs img, a[href^="/user/"] img').forEach(img => {
|
||||||
|
const link = img.closest('a');
|
||||||
|
if (link && (link.href.includes(lowerHref) || link.href.includes(exactHref))) {
|
||||||
|
img.src = newSrc;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Helper: apply banner update to relevant DOM nodes
|
// Helper: apply banner update to relevant DOM nodes
|
||||||
this.applyBannerUpdate = (banner_file, banner_position, banner_size, user) => {
|
this.applyBannerUpdate = (banner_file, banner_position, banner_size, user) => {
|
||||||
const userName = user || window.f0ckSession?.user;
|
const userName = user || window.f0ckSession?.user;
|
||||||
@@ -7439,6 +7561,73 @@ class NotificationSystem {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Helper: apply description update to relevant DOM nodes
|
||||||
|
this.applyDescriptionUpdate = (description, user) => {
|
||||||
|
const userName = user || window.f0ckSession?.user;
|
||||||
|
console.log('[SSE] applyDescriptionUpdate called for user:', userName, 'description:', description);
|
||||||
|
if (!userName) return;
|
||||||
|
|
||||||
|
// Escape quotes for selector
|
||||||
|
const safeUserName = userName.replace(/"/g, '\\"');
|
||||||
|
// Find the profile header for this user
|
||||||
|
const profileHead = document.querySelector(`.profile_head[data-banner-user="${safeUserName}"]`);
|
||||||
|
console.log('[SSE] applyDescriptionUpdate profileHead found?', !!profileHead);
|
||||||
|
|
||||||
|
if (profileHead) {
|
||||||
|
const descDisplay = profileHead.querySelector('#profile-desc-display div');
|
||||||
|
console.log('[SSE] applyDescriptionUpdate descDisplay found?', !!descDisplay);
|
||||||
|
|
||||||
|
if (descDisplay) {
|
||||||
|
if (!description || description.trim() === '') {
|
||||||
|
descDisplay.innerHTML = '<em style="color:var(--text-muted);">No description</em>';
|
||||||
|
} else {
|
||||||
|
const tempDiv = document.createElement('div');
|
||||||
|
tempDiv.textContent = description;
|
||||||
|
descDisplay.innerHTML = tempDiv.innerHTML.replace(/\n/g, '<br>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Also update the edit input if it exists (for the logged in user)
|
||||||
|
if (window.f0ckSession && userName === window.f0ckSession.user) {
|
||||||
|
const input = profileHead.querySelector('#inline-desc-input');
|
||||||
|
if (input) {
|
||||||
|
input.value = description || '';
|
||||||
|
console.log('[SSE] applyDescriptionUpdate input updated');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update any item page infoboxes
|
||||||
|
document.querySelectorAll(`.user-infobox-block[data-banner-user="${safeUserName}"]`).forEach(block => {
|
||||||
|
const infoboxDesc = block.querySelector('.user-infobox-description');
|
||||||
|
if (infoboxDesc) {
|
||||||
|
if (!description || description.trim() === '') {
|
||||||
|
infoboxDesc.innerHTML = '';
|
||||||
|
} else {
|
||||||
|
const tempDiv = document.createElement('div');
|
||||||
|
tempDiv.textContent = description;
|
||||||
|
infoboxDesc.innerHTML = tempDiv.innerHTML.replace(/\n/g, '<br>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Special case for settings page preview block
|
||||||
|
if (window.f0ckSession && userName === window.f0ckSession.user) {
|
||||||
|
const previewBlock = document.getElementById('live-profile-preview-box');
|
||||||
|
if (previewBlock) {
|
||||||
|
const previewDesc = previewBlock.querySelector('.user-infobox-description');
|
||||||
|
if (previewDesc) {
|
||||||
|
if (!description || description.trim() === '') {
|
||||||
|
previewDesc.innerHTML = 'Welcome to my profile! This is a live preview.';
|
||||||
|
} else {
|
||||||
|
const tempDiv = document.createElement('div');
|
||||||
|
tempDiv.textContent = description;
|
||||||
|
previewDesc.innerHTML = tempDiv.innerHTML.replace(/\n/g, '<br>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Re-apply own banner after every PJAX navigation and bfcache restore.
|
// Re-apply own banner after every PJAX navigation and bfcache restore.
|
||||||
// Fixes the case where SSE fired on the settings page before the item page DOM was loaded.
|
// Fixes the case where SSE fired on the settings page before the item page DOM was loaded.
|
||||||
const reapplyOwnBanner = () => {
|
const reapplyOwnBanner = () => {
|
||||||
|
|||||||
@@ -162,6 +162,14 @@ export const handleAvatarUpload = async (req, res) => {
|
|||||||
where user_id = ${+req.session.id}
|
where user_id = ${+req.session.id}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const payloadStr = JSON.stringify({
|
||||||
|
user_id: req.session.id,
|
||||||
|
user: req.session.user,
|
||||||
|
avatar_file: finalFilename,
|
||||||
|
avatar: null
|
||||||
|
});
|
||||||
|
await db`select pg_notify('profile_update', ${payloadStr})`;
|
||||||
|
|
||||||
console.log('[AVATAR HANDLER] Upload complete:', finalFilename);
|
console.log('[AVATAR HANDLER] Upload complete:', finalFilename);
|
||||||
return sendJson(res, {
|
return sendJson(res, {
|
||||||
success: true,
|
success: true,
|
||||||
@@ -225,6 +233,13 @@ export const handleAvatarDelete = async (req, res) => {
|
|||||||
where user_id = ${+req.session.id}
|
where user_id = ${+req.session.id}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const payloadStr = JSON.stringify({
|
||||||
|
user_id: req.session.id,
|
||||||
|
user: req.session.user,
|
||||||
|
avatar_file: null
|
||||||
|
});
|
||||||
|
await db`select pg_notify('profile_update', ${payloadStr})`;
|
||||||
|
|
||||||
console.log('[AVATAR HANDLER] Delete complete');
|
console.log('[AVATAR HANDLER] Delete complete');
|
||||||
return sendJson(res, { success: true, msg: 'Custom avatar removed' }, 200);
|
return sendJson(res, { success: true, msg: 'Custom avatar removed' }, 200);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -331,6 +331,14 @@ export default router => {
|
|||||||
`;
|
`;
|
||||||
// Sync session immediately
|
// Sync session immediately
|
||||||
if (req.session) req.session.username_color = color;
|
if (req.session) req.session.username_color = color;
|
||||||
|
|
||||||
|
const payloadStr = JSON.stringify({
|
||||||
|
user_id: req.session.id,
|
||||||
|
user: req.session.user,
|
||||||
|
username_color: color
|
||||||
|
});
|
||||||
|
await db`select pg_notify('profile_update', ${payloadStr})`;
|
||||||
|
|
||||||
return res.json({ success: true, color }, 200);
|
return res.json({ success: true, color }, 200);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Update Username Color error:', e);
|
console.error('Update Username Color error:', e);
|
||||||
@@ -420,6 +428,14 @@ export default router => {
|
|||||||
`;
|
`;
|
||||||
// Sync session immediately
|
// Sync session immediately
|
||||||
if (req.session) req.session.display_name = cleanDisplayName;
|
if (req.session) req.session.display_name = cleanDisplayName;
|
||||||
|
|
||||||
|
const payloadStr = JSON.stringify({
|
||||||
|
user_id: req.session.id,
|
||||||
|
user: req.session.user,
|
||||||
|
display_name: cleanDisplayName
|
||||||
|
});
|
||||||
|
await db`select pg_notify('profile_update', ${payloadStr})`;
|
||||||
|
|
||||||
return res.json({ success: true, display_name: cleanDisplayName, msg: 'Display name updated successfully' }, 200);
|
return res.json({ success: true, display_name: cleanDisplayName, msg: 'Display name updated successfully' }, 200);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Update Display Name error:', e);
|
console.error('Update Display Name error:', e);
|
||||||
@@ -448,6 +464,14 @@ export default router => {
|
|||||||
`;
|
`;
|
||||||
// Sync session immediately
|
// Sync session immediately
|
||||||
if (req.session) req.session.description = cleanDescription;
|
if (req.session) req.session.description = cleanDescription;
|
||||||
|
|
||||||
|
const payloadStr = JSON.stringify({
|
||||||
|
user_id: req.session.id,
|
||||||
|
user: req.session.user,
|
||||||
|
description: cleanDescription
|
||||||
|
});
|
||||||
|
await db`select pg_notify('profile_update', ${payloadStr})`;
|
||||||
|
|
||||||
return res.json({ success: true, description: cleanDescription }, 200);
|
return res.json({ success: true, description: cleanDescription }, 200);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Update Description error:', e);
|
console.error('Update Description error:', e);
|
||||||
|
|||||||
@@ -102,7 +102,10 @@ db.listen('profile_update', (payload) => {
|
|||||||
display_name: data.display_name,
|
display_name: data.display_name,
|
||||||
banner_file: data.banner_file,
|
banner_file: data.banner_file,
|
||||||
banner_position: data.banner_position,
|
banner_position: data.banner_position,
|
||||||
banner_size: data.banner_size
|
banner_size: data.banner_size,
|
||||||
|
avatar_file: data.avatar_file,
|
||||||
|
username_color: data.username_color,
|
||||||
|
description: data.description
|
||||||
};
|
};
|
||||||
client.send({ type: 'profile_update', data: publicData });
|
client.send({ type: 'profile_update', data: publicData });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -422,7 +422,37 @@
|
|||||||
});
|
});
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
location.reload();
|
let objectUrl = '/a/' + (data.avatar_file || data.file) + '?t=' + Date.now();
|
||||||
|
let wrapper = document.querySelector('.avatar-image-wrapper');
|
||||||
|
if (wrapper) {
|
||||||
|
let placeholder = wrapper.querySelector('.avatar-placeholder');
|
||||||
|
if (placeholder) {
|
||||||
|
let img = document.createElement('img');
|
||||||
|
img.className = 'profile-avatar-img';
|
||||||
|
img.src = objectUrl;
|
||||||
|
wrapper.insertBefore(img, placeholder);
|
||||||
|
placeholder.remove();
|
||||||
|
} else {
|
||||||
|
let img = wrapper.querySelector('.profile-avatar-img');
|
||||||
|
if (img) img.src = objectUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('.nav-avatar-img').forEach(img => img.src = objectUrl);
|
||||||
|
document.querySelectorAll('.comment-avatar img, .sidebar-avatar, .poll-voter-avatar, .rank-avatar').forEach(img => {
|
||||||
|
// Only replace if it matches the user's old avatar file, or if they didn't have one, just match if it links to their profile
|
||||||
|
const oldFile = '{{ user.avatar_file }}';
|
||||||
|
const oldId = '{{ user.avatar }}';
|
||||||
|
const isOldImage = (oldFile && img.src.includes('/a/' + oldFile)) || (oldId && img.src.includes('/t/' + oldId + '.webp'));
|
||||||
|
const link = img.closest('a');
|
||||||
|
const isUserLink = link && link.href.includes('/user/{{ user.user }}');
|
||||||
|
|
||||||
|
if (isOldImage || isUserLink) {
|
||||||
|
img.src = objectUrl;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
avatarEditBtn.innerHTML = '<i class="fa-solid fa-pen" style="font-size: 0.7em;"></i>';
|
||||||
|
avatarEditBtn.disabled = false;
|
||||||
} else {
|
} else {
|
||||||
alert(data.msg || 'Failed to upload avatar');
|
alert(data.msg || 'Failed to upload avatar');
|
||||||
avatarEditBtn.innerHTML = '<i class="fa-solid fa-pen" style="font-size: 0.7em;"></i>';
|
avatarEditBtn.innerHTML = '<i class="fa-solid fa-pen" style="font-size: 0.7em;"></i>';
|
||||||
@@ -471,7 +501,27 @@
|
|||||||
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': window.f0ckSession?.csrf_token },
|
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': window.f0ckSession?.csrf_token },
|
||||||
body: JSON.stringify(cPayload)
|
body: JSON.stringify(cPayload)
|
||||||
});
|
});
|
||||||
location.reload();
|
nameSaveBtn.disabled = false;
|
||||||
|
nameContainer.style.display = 'flex';
|
||||||
|
nameEditContainer.style.display = 'none';
|
||||||
|
|
||||||
|
const nameSpan = document.getElementById('nav-display-name');
|
||||||
|
if (nameSpan) {
|
||||||
|
nameSpan.style.color = color;
|
||||||
|
for (let i = nameSpan.childNodes.length - 1; i >= 0; i--) {
|
||||||
|
let node = nameSpan.childNodes[i];
|
||||||
|
if (node.nodeType === Node.TEXT_NODE && node.nodeValue.trim().length > 0) {
|
||||||
|
// Match and preserve any non-breaking spaces at the start (from admin/mod badges)
|
||||||
|
const match = node.nodeValue.match(new RegExp('^(\\\\s*)(.*)'));
|
||||||
|
node.nodeValue = (match ? match[1] : '') + (displayName ? displayName : '{{ user.user }}');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const bracket = document.getElementById('username-bracket');
|
||||||
|
if (bracket) {
|
||||||
|
bracket.style.display = displayName ? 'inline' : 'none';
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
alert('Error saving name/color');
|
alert('Error saving name/color');
|
||||||
nameSaveBtn.disabled = false;
|
nameSaveBtn.disabled = false;
|
||||||
@@ -507,7 +557,17 @@
|
|||||||
});
|
});
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
location.reload();
|
descSaveBtn.disabled = false;
|
||||||
|
descDisplay.style.display = 'block';
|
||||||
|
descEditContainer.style.display = 'none';
|
||||||
|
const descTextDiv = descDisplay.querySelector('div');
|
||||||
|
if (description.trim() === '') {
|
||||||
|
descTextDiv.innerHTML = '<em style="color:var(--text-muted);">No description</em>';
|
||||||
|
} else {
|
||||||
|
const tempDiv = document.createElement('div');
|
||||||
|
tempDiv.textContent = description;
|
||||||
|
descTextDiv.innerHTML = tempDiv.innerHTML.replace(new RegExp('\\\\n', 'g'), '<br>');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
alert(data.msg || 'Failed to update description');
|
alert(data.msg || 'Failed to update description');
|
||||||
descSaveBtn.disabled = false;
|
descSaveBtn.disabled = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user