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}