Dnishe/static/js/profile.js
2026-06-08 21:56:14 +00:00

360 lines
12 KiB
JavaScript

// profile customization logic
async function loadProfile() {
try {
const res = await fetch(`${API_URL}/profile`, {
headers: { 'Authorization': `Bearer ${token}` }
});
if (res.ok) {
const user = await res.json();
// populate form fields
profileAvatarInput.value = '';
profileDescInput.value = user.description || '';
profilePronounsInput.value = user.pronouns || '';
// show preview if avatar exists
setAvatarPreview(user.avatar_url);
// also update header avatar if present
updateHeaderAvatar(user.avatar_url);
}
} catch (e) {
console.error('error loading profile', e);
}
}
function displayProfileModal() {
profileModal.style.display = 'flex';
loadProfile();
}
async function saveProfile() {
const form = new FormData();
const file = profileAvatarInput.files && profileAvatarInput.files[0];
if (file) {
form.append('avatar_file', file);
}
form.append('description', profileDescInput.value.trim());
form.append('pronouns', profilePronounsInput.value.trim());
try {
const res = await fetch(`${API_URL}/profile`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
},
body: form
});
if (res.ok) {
const updated = await res.json();
updateHeaderAvatar(updated.avatar_url);
profileModal.style.display = 'none';
}
} catch (e) {
console.error('error saving profile', e);
}
}
function updateHeaderAvatar(url) {
if (url) {
let img = document.querySelector('.header-avatar');
if (!img) {
img = document.createElement('img');
img.className = 'header-avatar';
if (currentUserDisplay) {
currentUserDisplay.prepend(img);
}
}
img.src = url;
img.alt = 'avatar';
img.style.display = 'block';
img.onerror = function() {
this.style.display = 'none';
};
}
}
// profile modal preview
function setAvatarPreview(url) {
let prev = document.getElementById('avatar-preview');
if (!prev) {
prev = document.createElement('img');
prev.id = 'avatar-preview';
prev.style.maxWidth = '100px';
prev.style.maxHeight = '100px';
prev.style.borderRadius = '50%';
prev.style.objectFit = 'cover';
if (profileAvatarInput && profileAvatarInput.parentNode) {
profileAvatarInput.parentNode.insertBefore(prev, profileAvatarInput.nextSibling);
}
}
if (url) {
prev.src = url;
prev.style.display = 'block';
prev.onerror = function() {
this.style.display = 'none';
};
} else {
prev.style.display = 'none';
}
}
// View own profile
async function viewOwnProfile() {
if (!userProfileModal) return;
currentViewingUserId = userId; // Set to current user
try {
const res = await fetch(`${API_URL}/profile`, {
headers: { 'Authorization': `Bearer ${token}` }
});
if (res.ok) {
const user = await res.json();
// Set user info
userProfileUsername.textContent = user.username;
if (user.avatar_url && user.avatar_url.trim() !== '') {
userProfileAvatar.src = user.avatar_url;
userProfileAvatar.style.display = 'block';
} else {
userProfileAvatar.style.display = 'none';
}
if (user.pronouns && user.pronouns.trim() !== '') {
userProfilePronouns.textContent = user.pronouns;
userProfilePronouns.style.display = 'block';
} else {
userProfilePronouns.style.display = 'none';
}
if (user.description && user.description.trim() !== '') {
userProfileDescription.textContent = user.description;
} else {
userProfileDescription.textContent = '';
}
// Show "Edit Profile" button instead of "Add Friend"
userProfileAddFriendBtn.textContent = 'Edit Profile';
userProfileAddFriendBtn.classList.remove('added');
userProfileAddFriendBtn.disabled = false;
// Remove old event listeners and add new one
const newBtn = userProfileAddFriendBtn.cloneNode(true);
userProfileAddFriendBtn.parentNode.replaceChild(newBtn, userProfileAddFriendBtn);
userProfileAddFriendBtn = newBtn;
// Add click handler for edit profile
userProfileAddFriendBtn.addEventListener('click', () => {
userProfileModal.style.display = 'none';
displayProfileModal();
});
userProfileModal.style.display = 'flex';
}
} catch (error) {
console.error('Error loading own profile:', error);
}
}
// User profile preview modal functionality
let currentViewingUserId = null;
async function showUserProfile(userId) {
if (!userProfileModal) return;
currentViewingUserId = userId;
try {
const res = await fetch(`${API_URL}/users/${userId}`, {
headers: { 'Authorization': `Bearer ${token}` }
});
if (res.ok) {
const user = await res.json();
// Set user info
userProfileUsername.textContent = user.username;
// Handle avatar - check if URL exists and is not empty
if (user.avatar_url && user.avatar_url.trim() !== '') {
userProfileAvatar.src = user.avatar_url;
userProfileAvatar.style.display = 'block';
userProfileAvatar.onerror = function() {
// Fallback if image fails to load
this.style.display = 'none';
};
} else {
// Hide avatar if no URL
userProfileAvatar.style.display = 'none';
}
// Handle pronouns
if (user.pronouns && user.pronouns.trim() !== '') {
userProfilePronouns.textContent = user.pronouns;
userProfilePronouns.style.display = 'block';
} else {
userProfilePronouns.style.display = 'none';
}
// Handle description
if (user.description && user.description.trim() !== '') {
userProfileDescription.textContent = user.description;
} else {
userProfileDescription.textContent = '';
}
// Check if already friends
const isFriend = friends.some(f => f.id === user.id);
const isSelf = String(user.id) === String(userId);
if (isFriend) {
userProfileAddFriendBtn.textContent = 'Friends';
userProfileAddFriendBtn.classList.add('added');
userProfileAddFriendBtn.disabled = true;
} else if (isSelf) {
userProfileAddFriendBtn.textContent = 'Your Profile';
userProfileAddFriendBtn.classList.add('added');
userProfileAddFriendBtn.disabled = true;
} else {
userProfileAddFriendBtn.textContent = 'Add Friend';
userProfileAddFriendBtn.classList.remove('added');
userProfileAddFriendBtn.disabled = false;
}
userProfileModal.style.display = 'flex';
}
} catch (error) {
console.error('Error loading user profile:', error);
}
}
async function addFriendFromProfile() {
if (!currentViewingUserId || userProfileAddFriendBtn.disabled) return;
// Get username from the display
const username = userProfileUsername.textContent;
try {
const res = await fetch(`${API_URL}/friend-request`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({ username: username })
});
if (res.ok) {
userProfileAddFriendBtn.textContent = 'Request Sent';
userProfileAddFriendBtn.classList.add('added');
userProfileAddFriendBtn.disabled = true;
} else {
const data = await res.json();
alert(data.error || 'Error sending friend request');
}
} catch (error) {
console.error('Error adding friend:', error);
}
}
function initUserProfileListeners() {
// Close button
if (userProfileCloseBtn) {
userProfileCloseBtn.addEventListener('click', () => {
if (userProfileModal) userProfileModal.style.display = 'none';
});
}
// Close on background click
if (userProfileModal) {
userProfileModal.addEventListener('click', (e) => {
if (e.target === userProfileModal) {
userProfileModal.style.display = 'none';
}
});
}
// Add friend button
if (userProfileAddFriendBtn) {
userProfileAddFriendBtn.addEventListener('click', addFriendFromProfile);
}
}
// Make message usernames clickable to view profile
function initMessageUsernameClickHandlers() {
// This will be called after messages are rendered
document.addEventListener('click', (e) => {
const authorSpan = e.target.closest('.message-author');
if (authorSpan && !authorSpan.classList.contains('own-author')) {
const messageEl = authorSpan.closest('.message');
if (messageEl) {
const senderId = messageEl.getAttribute('data-sender-id');
if (senderId && String(senderId) !== String(userId)) {
showUserProfile(senderId);
}
}
}
});
}
function initProfileListeners() {
// Initialize user profile modal listeners
initUserProfileListeners();
initMessageUsernameClickHandlers();
// View own profile button
const viewProfileBtn = document.getElementById('view-profile-btn');
if (viewProfileBtn) {
try {
viewProfileBtn.addEventListener('click', viewOwnProfile);
} catch(e) {
console.error('viewProfileBtn attach', e);
}
} else if (profileBtn) {
// Fallback to old button
try {
profileBtn.addEventListener('click', viewOwnProfile);
} catch(e) {
console.error('profileBtn attach', e);
}
}
if (profileCloseBtn) {
try {
profileCloseBtn.addEventListener('click', () => {
profileModal.style.display = 'none';
});
} catch(e) {
console.error('profileCloseBtn attach', e);
}
}
if (profileModal) {
try {
profileModal.addEventListener('click', (e) => {
if (e.target === profileModal) profileModal.style.display = 'none';
});
} catch(e) {
console.error('profileModal attach', e);
}
}
if (profileSaveBtn) {
try {
profileSaveBtn.addEventListener('click', saveProfile);
} catch(e) {
console.error('profileSaveBtn attach', e);
}
}
// watch file input changes for preview
if (profileAvatarInput) {
profileAvatarInput.addEventListener('change', () => {
const file = profileAvatarInput.files[0];
if (file) {
const reader = new FileReader();
reader.onload = e => setAvatarPreview(e.target.result);
reader.readAsDataURL(file);
}
});
}
}