111 lines
4.3 KiB
JavaScript
111 lines
4.3 KiB
JavaScript
(() => {
|
|
const profileForm = document.querySelector('#profile-form');
|
|
const passwordForm = document.querySelector('#password-form');
|
|
const mastodonForm = document.querySelector('#mastodon-form');
|
|
const profileLogoutButton = document.querySelector('#logout-button');
|
|
const accessToken = localStorage.getItem('linklogAccessToken');
|
|
const defaultMastodonInstance = 'mastodon.social';
|
|
const defaultPostPrefix = 'From my #LinkLog: "';
|
|
|
|
function authHeaders(includeJson = false) {
|
|
return {
|
|
...(includeJson ? {'Content-Type': 'application/json'} : {}),
|
|
...(accessToken ? {Authorization: `Bearer ${accessToken}`} : {}),
|
|
};
|
|
}
|
|
|
|
function setStatus(selector, message, isError = false) {
|
|
const status = document.querySelector(selector);
|
|
status.textContent = message;
|
|
status.style.color = isError ? '#b91c1c' : '#166534';
|
|
}
|
|
|
|
async function loadProfile() {
|
|
const response = await fetch('/api/user/me', {headers: authHeaders()});
|
|
if (!response.ok) throw new Error('Could not load profile');
|
|
const profile = await response.json();
|
|
document.querySelector('#username').textContent = profile.username || '';
|
|
document.querySelector('#email').value = profile.email || '';
|
|
document.querySelector('#bio').value = profile.bio || '';
|
|
const avatarPreview = document.querySelector('#avatar-preview');
|
|
if (profile.avatar_url) {
|
|
avatarPreview.src = profile.avatar_url;
|
|
avatarPreview.classList.remove('hidden');
|
|
}
|
|
if (profile.is_admin) {
|
|
document.querySelector('#admin-link').classList.remove('hidden');
|
|
}
|
|
profileLogoutButton.classList.remove('hidden');
|
|
}
|
|
|
|
async function loadMastodonConfig() {
|
|
const response = await fetch('/api/user/plugins/mastodon', {headers: authHeaders()});
|
|
if (!response.ok) throw new Error('Could not load Mastodon settings');
|
|
const config = await response.json();
|
|
document.querySelector('#mastodon-instance').value = config.instance || defaultMastodonInstance;
|
|
document.querySelector('#mastodon-access-token').value = config.access_token || '';
|
|
document.querySelector('#mastodon-post-prefix').value = config.post_prefix || defaultPostPrefix;
|
|
}
|
|
|
|
profileForm.addEventListener('submit', async (event) => {
|
|
event.preventDefault();
|
|
const formData = new FormData(profileForm);
|
|
formData.delete('avatar');
|
|
const response = await fetch('/api/user/me', {
|
|
method: 'PUT',
|
|
headers: authHeaders(true),
|
|
body: JSON.stringify(Object.fromEntries(formData)),
|
|
});
|
|
setStatus('#profile-status', response.ok ? 'Profile saved.' : 'Could not save profile.', !response.ok);
|
|
});
|
|
|
|
document.querySelector('#avatar-file').addEventListener('change', async (event) => {
|
|
const file = event.target.files[0];
|
|
if (!file) return;
|
|
const formData = new FormData();
|
|
formData.append('avatar', file);
|
|
const response = await fetch('/api/user/avatar', {
|
|
method: 'POST',
|
|
headers: authHeaders(),
|
|
body: formData,
|
|
});
|
|
if (!response.ok) {
|
|
setStatus('#profile-status', 'Could not upload avatar.', true);
|
|
return;
|
|
}
|
|
const data = await response.json();
|
|
const avatarPreview = document.querySelector('#avatar-preview');
|
|
avatarPreview.src = data.avatar_url;
|
|
avatarPreview.classList.remove('hidden');
|
|
setStatus('#profile-status', 'Avatar uploaded.');
|
|
});
|
|
|
|
mastodonForm.addEventListener('submit', async (event) => {
|
|
event.preventDefault();
|
|
const formData = new FormData(mastodonForm);
|
|
const response = await fetch('/api/user/plugins/mastodon', {
|
|
method: 'PUT',
|
|
headers: authHeaders(true),
|
|
body: JSON.stringify(Object.fromEntries(formData)),
|
|
});
|
|
setStatus('#mastodon-status', response.ok ? 'Mastodon settings saved.' : 'Could not save Mastodon settings.', !response.ok);
|
|
});
|
|
|
|
passwordForm.addEventListener('submit', async (event) => {
|
|
event.preventDefault();
|
|
const response = await fetch('/api/user/password', {
|
|
method: 'PUT',
|
|
headers: authHeaders(true),
|
|
body: JSON.stringify(Object.fromEntries(new FormData(passwordForm))),
|
|
});
|
|
const status = document.querySelector('#password-status');
|
|
status.textContent = response.ok ? 'Password changed.' : 'Could not change password.';
|
|
status.style.color = response.ok ? '#94e2d5' : '#f38ba8';
|
|
if (response.ok) passwordForm.reset();
|
|
});
|
|
|
|
Promise.all([loadProfile(), loadMastodonConfig()]).catch((error) => {
|
|
setStatus('#profile-status', accessToken ? error.message : 'Please sign in first.', true);
|
|
});
|
|
})();
|