Adrià Vilanova Martínez | 4768e81 | 2022-02-01 13:41:28 +0100 | [diff] [blame] | 1 | import {MDCTooltip} from '@material/tooltip'; |
| 2 | |
| 3 | import {createExtBadge} from './common.js'; |
| 4 | |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 5 | // Each entry includes the following information in order: |
| 6 | // - ID |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 7 | // - Codename |
| 8 | // - Color (for the label in the legend) |
| 9 | const kDataKeys = [ |
Adrià Vilanova Martínez | 69c3050 | 2022-01-28 20:47:08 +0100 | [diff] [blame] | 10 | [4, 'recommended', '#34A853'], |
| 11 | [6, 'replies', '#DADCE0'], |
| 12 | [5, 'questions', '#77909D'], |
Adrià Vilanova Martínez | 22d5603 | 2023-07-22 12:28:51 +0200 | [diff] [blame] | 13 | [7, 'communityvideos', '#F4511E'], |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 14 | ]; |
| 15 | const kRoles = { |
| 16 | 1: 'bronze', |
| 17 | 2: 'silver', |
| 18 | 3: 'gold', |
| 19 | 4: 'platinum', |
| 20 | 5: 'diamond', |
| 21 | 10: 'community_manager', |
| 22 | 20: 'community_specialist', |
| 23 | 100: 'google_employee', |
| 24 | 30: 'alumnus', |
| 25 | }; |
| 26 | |
| 27 | export default class PerForumStatsSection { |
avm99963 | 37601bc | 2022-02-21 10:36:45 +0100 | [diff] [blame] | 28 | constructor(existingChartSection, profile, locale, isCommunityConsole) { |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 29 | this.locale = locale; |
avm99963 | 37601bc | 2022-02-21 10:36:45 +0100 | [diff] [blame] | 30 | this.isCommunityConsole = isCommunityConsole; |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 31 | this.parseAndSetData(profile); |
| 32 | this.buildDOM(existingChartSection); |
| 33 | if (this.data.length) this.injectChart(this.data[0]?.id); |
| 34 | } |
| 35 | |
| 36 | parseAndSetData(profile) { |
| 37 | const forumUserInfos = profile?.[1]?.[7] ?? []; |
| 38 | const forumTitles = profile?.[1]?.[8] ?? []; |
| 39 | |
| 40 | const forumUserInfoIDs = forumUserInfos.map(ui => ui[1]); |
| 41 | const forumTitleIDs = forumTitles.map(t => t[1]); |
| 42 | const intersectionForumIDs = |
| 43 | forumUserInfoIDs.filter(id => forumTitleIDs.includes(id)); |
| 44 | |
| 45 | this.data = []; |
| 46 | for (const id of intersectionForumIDs) { |
avm99963 | 37601bc | 2022-02-21 10:36:45 +0100 | [diff] [blame] | 47 | const fui = forumUserInfos.find(ui => ui?.[1] === id)?.[2]; |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 48 | const numMessages = kDataKeys.reduce((prevVal, key) => { |
| 49 | if (!fui?.[key[0]]) return prevVal; |
| 50 | return prevVal + fui[key[0]].reduce((prevVal, userActivity) => { |
| 51 | return prevVal + (userActivity?.[3] ?? 0); |
| 52 | }, /* initialValue = */ 0); |
| 53 | }, /* initialValue = */ 0); |
| 54 | this.data.push({ |
| 55 | id, |
avm99963 | 37601bc | 2022-02-21 10:36:45 +0100 | [diff] [blame] | 56 | forumTitle: forumTitles.find(t => t?.[1] === id)?.[2], |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 57 | forumUserInfo: fui, |
| 58 | numMessages, |
| 59 | }); |
| 60 | } |
| 61 | this.data.sort((a, b) => { |
| 62 | // First sort by number of messages |
| 63 | if (b.numMessages > a.numMessages) return 1; |
| 64 | if (b.numMessages < a.numMessages) return -1; |
| 65 | // Then sort by name |
| 66 | return a.forumTitle.localeCompare( |
| 67 | b.forumTitle, 'en', {sensitivity: 'base'}); |
| 68 | }); |
| 69 | } |
| 70 | |
| 71 | buildDOM(existingChartSection) { |
| 72 | let section = document.createElement('div'); |
| 73 | section.classList.add('scTailwindUser_profileUserprofilesection'); |
| 74 | |
| 75 | let root = document.createElement('div'); |
| 76 | root.classList.add( |
| 77 | 'scTailwindSharedActivitychartroot', |
| 78 | 'TWPT-scTailwindSharedActivitychartroot'); |
| 79 | |
| 80 | let title = document.createElement('h2'); |
| 81 | title.classList.add('scTailwindSharedActivitycharttitle'); |
Adrià Vilanova Martínez | 4768e81 | 2022-02-01 13:41:28 +0100 | [diff] [blame] | 82 | |
avm99963 | 37601bc | 2022-02-21 10:36:45 +0100 | [diff] [blame] | 83 | let badge, badgeTooltip; |
| 84 | if (this.isCommunityConsole) { |
| 85 | [badge, badgeTooltip] = createExtBadge(); |
| 86 | } else { |
| 87 | badge = document.createElement('span'); |
| 88 | badge.classList.add('TWPT-badge'); |
| 89 | |
| 90 | var badgeImg = document.createElement('img'); |
| 91 | badgeImg.src = |
| 92 | 'https://fonts.gstatic.com/s/i/materialicons/repeat/v6/24px.svg'; |
| 93 | |
| 94 | badge.appendChild(badgeImg); |
| 95 | } |
| 96 | |
Adrià Vilanova Martínez | 4768e81 | 2022-02-01 13:41:28 +0100 | [diff] [blame] | 97 | let titleText = document.createElement('span'); |
avm99963 | 37601bc | 2022-02-21 10:36:45 +0100 | [diff] [blame] | 98 | titleText.textContent = |
| 99 | chrome.i18n.getMessage('inject_perforumstats_heading'); |
Adrià Vilanova Martínez | 4768e81 | 2022-02-01 13:41:28 +0100 | [diff] [blame] | 100 | |
| 101 | title.append(badge, titleText); |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 102 | |
| 103 | let selector = this.createForumSelector(); |
| 104 | |
| 105 | let chartEl = document.createElement('div'); |
| 106 | chartEl.classList.add('scTailwindSharedActivitychartchart'); |
Adrià Vilanova Martínez | 69c3050 | 2022-01-28 20:47:08 +0100 | [diff] [blame] | 107 | chartEl.setAttribute('data-twpt-per-forum-chart', ''); |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 108 | |
| 109 | root.append(title, selector, chartEl); |
| 110 | section.append(root); |
| 111 | existingChartSection.after(section); |
avm99963 | 37601bc | 2022-02-21 10:36:45 +0100 | [diff] [blame] | 112 | if (this.isCommunityConsole) new MDCTooltip(badgeTooltip); |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 113 | } |
| 114 | |
| 115 | getAplosData(forumId) { |
| 116 | let aplosData = []; |
Adrià Vilanova Martínez | 69c3050 | 2022-01-28 20:47:08 +0100 | [diff] [blame] | 117 | for (const [key, name, color] of kDataKeys) { |
Adrià Vilanova Martínez | 217e5f0 | 2023-07-22 20:55:50 +0200 | [diff] [blame] | 118 | let rawData = this.data.find(f => f.id == forumId)?.forumUserInfo?.[key]; |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 119 | let data; |
avm99963 | 37601bc | 2022-02-21 10:36:45 +0100 | [diff] [blame] | 120 | if (!rawData) { |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 121 | data = []; |
avm99963 | 37601bc | 2022-02-21 10:36:45 +0100 | [diff] [blame] | 122 | } else { |
| 123 | // We're filtering empty strings since in the public forum there a lose |
| 124 | // conversion takes place and the first element of the array is always |
| 125 | // null, which breaks the Aplos graph rendering. |
| 126 | data = |
| 127 | rawData.map(m => JSON.stringify(Object.values(m))).filter(m => !!m); |
| 128 | } |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 129 | aplosData.push({ |
| 130 | color, |
| 131 | data, |
Adrià Vilanova Martínez | 69c3050 | 2022-01-28 20:47:08 +0100 | [diff] [blame] | 132 | label: chrome.i18n.getMessage('inject_perforumstats_chart_' + name), |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 133 | name, |
| 134 | }); |
| 135 | } |
| 136 | return aplosData; |
| 137 | } |
| 138 | |
Adrià Vilanova Martínez | 69c3050 | 2022-01-28 20:47:08 +0100 | [diff] [blame] | 139 | getMessagesString(num) { |
| 140 | if (num == 1) { |
| 141 | return chrome.i18n.getMessage( |
| 142 | 'inject_perforumstats_nummessages_singular'); |
| 143 | } |
| 144 | return chrome.i18n.getMessage( |
| 145 | 'inject_perforumstats_nummessages_plural', [num]); |
| 146 | } |
| 147 | |
| 148 | getForumOptionString(forumTitle, labels) { |
| 149 | if (labels.length == 0) return forumTitle; |
| 150 | if (labels.length == 1) |
| 151 | return chrome.i18n.getMessage( |
| 152 | 'inject_perforumstats_forumoption_1helper', [forumTitle, ...labels]); |
| 153 | if (labels.length == 2) |
| 154 | return chrome.i18n.getMessage( |
| 155 | 'inject_perforumstats_forumoption_2helpers', [forumTitle, ...labels]); |
| 156 | |
| 157 | // If labels.length > 3, this is unexpected. Here's a sensible fallback: |
| 158 | return forumTitle + ' (' + labels.join(', ') + ')'; |
| 159 | } |
| 160 | |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 161 | createForumSelector() { |
| 162 | let div = document.createElement('div'); |
| 163 | div.classList.add('TWPT-select-container'); |
| 164 | |
| 165 | let select = document.createElement('select'); |
| 166 | let noPostsGroup; |
| 167 | let noPostsGroupFlag = false; |
| 168 | for (const forumData of this.data) { |
| 169 | const hasPosted = forumData.numMessages > 0; |
| 170 | |
| 171 | if (!hasPosted && !noPostsGroupFlag) { |
| 172 | noPostsGroup = document.createElement('optgroup'); |
Adrià Vilanova Martínez | 69c3050 | 2022-01-28 20:47:08 +0100 | [diff] [blame] | 173 | noPostsGroup.label = |
| 174 | chrome.i18n.getMessage('inject_perforumstats_optgroup_notposted'); |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 175 | noPostsGroupFlag = true; |
| 176 | } |
| 177 | |
Adrià Vilanova Martínez | 69c3050 | 2022-01-28 20:47:08 +0100 | [diff] [blame] | 178 | let additionalLabels = []; |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 179 | if (hasPosted) |
Adrià Vilanova Martínez | 69c3050 | 2022-01-28 20:47:08 +0100 | [diff] [blame] | 180 | additionalLabels.push(this.getMessagesString(forumData.numMessages)); |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 181 | let role = forumData.forumUserInfo?.[1]?.[3] ?? 0; |
Adrià Vilanova Martínez | 69c3050 | 2022-01-28 20:47:08 +0100 | [diff] [blame] | 182 | if (role) |
| 183 | additionalLabels.push(chrome.i18n.getMessage( |
| 184 | 'inject_perforumstats_role_' + kRoles[role])); |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 185 | |
| 186 | let option = document.createElement('option'); |
Adrià Vilanova Martínez | 69c3050 | 2022-01-28 20:47:08 +0100 | [diff] [blame] | 187 | option.textContent = |
| 188 | this.getForumOptionString(forumData.forumTitle, additionalLabels); |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 189 | option.value = forumData.id; |
| 190 | if (hasPosted) |
| 191 | select.append(option); |
| 192 | else |
| 193 | noPostsGroup.append(option); |
| 194 | } |
| 195 | if (noPostsGroupFlag) select.append(noPostsGroup); |
| 196 | select.addEventListener('change', e => { |
| 197 | let forumId = e.target.value; |
| 198 | this.injectChart(forumId); |
| 199 | }); |
| 200 | |
| 201 | div.append(select); |
| 202 | return div; |
| 203 | } |
| 204 | |
| 205 | injectChart(forumId) { |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 206 | let data = this.getAplosData(forumId); |
| 207 | let metadata = { |
| 208 | activities: [], |
| 209 | finalMonth: undefined, |
| 210 | locale: this.locale, |
| 211 | shouldDisableTransitions: true, |
| 212 | }; |
Adrià Vilanova Martínez | 69c3050 | 2022-01-28 20:47:08 +0100 | [diff] [blame] | 213 | let chartTitle = chrome.i18n.getMessage('inject_perforumstats_chart_label'); |
| 214 | const message = { |
| 215 | action: 'renderProfileActivityChart', |
| 216 | prefix: 'TWPT-extrainfo', |
| 217 | data, |
| 218 | metadata, |
| 219 | chartTitle, |
| 220 | }; |
| 221 | window.postMessage(message, '*'); |
Adrià Vilanova Martínez | 4f56d56 | 2022-01-26 00:23:27 +0100 | [diff] [blame] | 222 | } |
| 223 | } |