Thread viewer for Bluesky
1class Menu { 2 constructor() { 3 this.menuElement = $id('account_menu'); 4 this.icon = $id('account'); 5 6 this.setupEvents(); 7 } 8 9 setupEvents() { 10 let html = $(document.body.parentNode); 11 12 html.addEventListener('click', (e) => { 13 this.menuElement.style.visibility = 'hidden'; 14 }); 15 16 let homeLink = $(this.menuElement.querySelector('a[href="?"]'), HTMLLinkElement); 17 homeLink.href = location.origin + location.pathname; 18 19 this.icon.addEventListener('click', (e) => { 20 e.stopPropagation(); 21 this.toggleAccountMenu(); 22 }); 23 24 this.menuElement.addEventListener('click', (e) => { 25 e.stopPropagation(); 26 }); 27 28 $(this.menuElement.querySelector('a[data-action=biohazard]')).addEventListener('click', (e) => { 29 e.preventDefault(); 30 31 let hazards = document.querySelectorAll('p.hidden-replies, .content > .post.blocked, .blocked > .load-post'); 32 33 if (window.biohazardEnabled === false) { 34 window.biohazardEnabled = true; 35 localStorage.setItem('biohazard', 'true'); 36 this.toggleMenuButtonCheck('biohazard', true); 37 Array.from(hazards).forEach(p => { $(p).style.display = 'block' }); 38 } else { 39 window.biohazardEnabled = false; 40 localStorage.setItem('biohazard', 'false'); 41 this.toggleMenuButtonCheck('biohazard', false); 42 Array.from(hazards).forEach(p => { $(p).style.display = 'none' }); 43 } 44 }); 45 46 $(this.menuElement.querySelector('a[data-action=incognito]')).addEventListener('click', (e) => { 47 e.preventDefault(); 48 49 if (window.isIncognito) { 50 localStorage.removeItem('incognito'); 51 } else { 52 localStorage.setItem('incognito', '1'); 53 } 54 55 location.reload(); 56 }); 57 58 $(this.menuElement.querySelector('a[data-action=login]')).addEventListener('click', (e) => { 59 e.preventDefault(); 60 61 showDialog(loginDialog); 62 this.menuElement.style.visibility = 'hidden'; 63 }); 64 65 $(this.menuElement.querySelector('a[data-action=logout]')).addEventListener('click', (e) => { 66 e.preventDefault(); 67 logOut(); 68 }); 69 } 70 71 toggleAccountMenu() { 72 this.menuElement.style.visibility = (this.menuElement.style.visibility == 'visible') ? 'hidden' : 'visible'; 73 } 74 75 /** @param {string} buttonName */ 76 77 showMenuButton(buttonName) { 78 let button = $(this.menuElement.querySelector(`a[data-action=${buttonName}]`)); 79 let item = $(button.parentNode); 80 item.style.display = 'list-item'; 81 } 82 83 /** @param {string} buttonName */ 84 85 hideMenuButton(buttonName) { 86 let button = $(this.menuElement.querySelector(`a[data-action=${buttonName}]`)); 87 let item = $(button.parentNode); 88 item.style.display = 'none'; 89 } 90 91 /** @param {string} buttonName, @param {boolean} state */ 92 93 toggleMenuButtonCheck(buttonName, state) { 94 let button = $(this.menuElement.querySelector(`a[data-action=${buttonName}]`)); 95 let check = $(button.querySelector('.check')); 96 check.style.display = (state) ? 'inline' : 'none'; 97 } 98 99 /** @param {boolean | 'incognito'} loggedIn, @param {string | undefined | null} [avatar] */ 100 101 showLoggedInStatus(loggedIn, avatar) { 102 if (loggedIn === true && avatar) { 103 let button = $(this.icon.querySelector('i')); 104 105 let img = $tag('img.avatar', { src: avatar }); 106 img.style.display = 'none'; 107 img.addEventListener('load', () => { 108 button.remove(); 109 img.style.display = 'inline'; 110 }); 111 img.addEventListener('error', () => { 112 this.showLoggedInStatus(true, null); 113 }) 114 115 this.icon.append(img); 116 } else if (loggedIn === false) { 117 this.icon.innerHTML = `<i class="fa-regular fa-user-circle fa-xl"></i>`; 118 } else if (loggedIn === 'incognito') { 119 this.icon.innerHTML = `<i class="fa-solid fa-user-secret fa-lg"></i>`; 120 } else { 121 this.icon.innerHTML = `<i class="fa-solid fa-user-circle fa-xl"></i>`; 122 } 123 } 124 125 /** @returns {Promise<void>} */ 126 127 async loadCurrentUserAvatar() { 128 try { 129 let url = await api.loadCurrentUserAvatar(); 130 this.showLoggedInStatus(true, url); 131 } catch (error) { 132 console.log(error); 133 this.showLoggedInStatus(true, null); 134 } 135 } 136}