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}