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