Localize extraInfo
Fixed: twpowertools:95
Change-Id: I3ef8102948af2b9c6143b70cdf2e1c61c1b18a8f
diff --git a/src/contentScripts/communityConsole/extraInfo.js b/src/contentScripts/communityConsole/extraInfo.js
index 9b1cd9a..873a62f 100644
--- a/src/contentScripts/communityConsole/extraInfo.js
+++ b/src/contentScripts/communityConsole/extraInfo.js
@@ -13,10 +13,11 @@
const kViewThreadResponse = 'TWPT_ViewThreadResponse';
const kViewForumResponse = 'TWPT_ViewForumResponse';
+// Used to match each category with the corresponding string.
const kAbuseCategories = [
- ['1', 'Account'],
- ['2', 'Display name'],
- ['3', 'Avatar'],
+ ['1', 'account'],
+ ['2', 'displayname'],
+ ['3', 'avatar'],
];
const kAbuseViolationCategories = {
0: 'NO_VIOLATION',
@@ -25,6 +26,16 @@
3: 'CSAI_VIOLATION',
4: 'OTHER_VIOLATION',
};
+const kAbuseViolationCategoriesI18n = {
+ 0: 'noviolation',
+ 1: 'communitypolicy',
+ 2: 'legal',
+ 3: 'csai',
+ 4: 'other',
+};
+
+// The following array will appear in the interface as is (without being
+// translated).
const kAbuseViolationTypes = {
0: 'UNSPECIFIED',
23: 'ACCOUNT_DISABLED',
@@ -145,6 +156,28 @@
18: 'TERRORISM_SUPPORT',
56: 'CSAI_WORST_OF_WORST',
};
+
+// These values will be translated
+const kItemMetadataStateI18n = {
+ 1: 'published',
+ 2: 'draft',
+ 3: 'automated_abuse_take_down_hide',
+ 4: 'automated_abuse_take_down_delete',
+ 13: 'automated_abuse_reinstate',
+ 10: 'automated_off_topic_hide',
+ 14: 'automated_flagged_pending_manual_review',
+ 5: 'user_flagged_pending_manual_review',
+ 6: 'owner_deleted',
+ 7: 'manual_take_down_hide',
+ 17: 'manual_profile_take_down_suspend',
+ 8: 'manual_take_down_delete',
+ 18: 'reinstate_profile_takedown',
+ 9: 'reinstate_abuse_takedown',
+ 11: 'clear_off_topic',
+ 12: 'confirm_off_topic',
+ 15: 'googler_off_topic_hide',
+ 16: 'expert_flagged_pending_manual_review',
+};
const kItemMetadataState = {
0: 'UNDEFINED',
1: 'PUBLISHED',
@@ -166,10 +199,6 @@
15: 'GOOGLER_OFF_TOPIC_HIDE',
16: 'EXPERT_FLAGGED_PENDING_MANUAL_REVIEW',
};
-const kShadowBlockReason = {
- 0: 'REASON_UNDEFINED',
- 1: 'ULTRON_LOW_QUALITY',
-};
export default class ExtraInfo {
constructor() {
@@ -297,18 +326,6 @@
for (const tooltip of tooltips) new MDCTooltip(tooltip);
}
- fieldInfo(field, value) {
- let span = document.createElement('span');
- span.append(document.createTextNode(field + ': '));
-
- let valueEl = document.createElement('span');
- valueEl.style.fontFamily = 'monospace';
- valueEl.textContent = value;
-
- span.append(valueEl);
- return span;
- }
-
/**
* Profile functionality
*/
@@ -329,10 +346,16 @@
let info = [];
const abuseViolationCategory = profile.body?.['1']?.['6'];
if (abuseViolationCategory) {
- info.push(this.fieldInfo(
- 'Abuse category',
- kAbuseViolationCategories[abuseViolationCategory] ??
- abuseViolationCategory));
+ let avCat = document.createElement('span');
+ avCat.textContent = chrome.i18n.getMessage(
+ 'inject_extrainfo_profile_abusecategory',
+ [chrome.i18n.getMessage(
+ 'inject_extrainfo_profile_abusecategory_' +
+ kAbuseViolationCategoriesI18n[abuseViolationCategory]) ??
+ abuseViolationCategory]);
+ avCat.title = kAbuseViolationCategories[abuseViolationCategory] ??
+ abuseViolationCategory;
+ info.push(avCat);
}
const profileAbuse = profile.body?.['1']?.['1']?.['8'];
@@ -340,15 +363,16 @@
for (const [index, category] of kAbuseCategories) {
const violation = profileAbuse?.[index]?.['1']?.['1'];
if (violation) {
- info.push(this.fieldInfo(
- category + ' policy violation',
- kAbuseViolationTypes[violation]));
+ info.push(chrome.i18n.getMessage(
+ 'inject_extrainfo_profile_abuse_' + category,
+ [kAbuseViolationTypes[violation]]));
}
}
const appealCount = profileAbuse?.['4'];
if (appealCount !== undefined)
- info.push(this.fieldInfo('Number of appeals', appealCount));
+ info.push(chrome.i18n.getMessage(
+ 'inject_extrainfo_profile_appealsnum', [appealCount]));
this.addExtraInfoElement(info, card, true);
})
@@ -377,6 +401,13 @@
?.textContent;
}
+ getUsageCountString(num) {
+ if (num == 1)
+ return chrome.i18n.getMessage('inject_extrainfo_crs_used_singular');
+
+ return chrome.i18n.getMessage('inject_extrainfo_crs_used_plural', [num]);
+ }
+
// Inject usage stats in the |tags| component of a CR
injectAtCR(tags, isExpanded) {
waitFor(
@@ -416,7 +447,7 @@
const [badge, badgeTooltip] = createExtBadge();
let label = document.createElement('span');
- label.textContent = 'Used ' + (cr['8'] ?? '0') + ' times';
+ label.textContent = this.getUsageCountString(cr['8'] ?? '0');
content.append(badge, label);
container.append(content);
@@ -428,7 +459,10 @@
if (cr['9']) {
const lastUsedTime = Math.floor(parseInt(cr['9']) / 1e3);
let date = (new Date(lastUsedTime)).toLocaleString();
- createPlainTooltip(label, 'Last used: ' + date);
+ createPlainTooltip(
+ label,
+ chrome.i18n.getMessage(
+ 'inject_extrainfo_crs_lastused', [date]));
}
break;
@@ -460,11 +494,15 @@
const now = Date.now();
if (endPendingStateTimestampMicros && endPendingStateTimestamp > now) {
let span = document.createElement('span');
- span.textContent = 'Only visible to badged users';
+ span.textContent =
+ chrome.i18n.getMessage('inject_extrainfo_message_pendingstate');
let date = new Date(endPendingStateTimestamp).toLocaleString();
- let pendingTooltip =
- createPlainTooltip(span, 'Visible after ' + date, false);
+ let pendingTooltip = createPlainTooltip(
+ span,
+ chrome.i18n.getMessage(
+ 'inject_extrainfo_message_pendingstate_tooltip', [date]),
+ false);
return [span, pendingTooltip];
}
@@ -475,16 +513,26 @@
let info = [];
const state = itemMetadata?.['1'];
- if (state && state != 1)
- info.push(this.fieldInfo('State', kItemMetadataState[state] ?? state));
+ if (state && state != 1) {
+ let span = document.createElement('span');
+ span.textContent = chrome.i18n.getMessage(
+ 'inject_extrainfo_message_state',
+ [chrome.i18n.getMessage(
+ 'inject_extrainfo_message_state_' +
+ kItemMetadataStateI18n[state]) ??
+ state]);
+ span.title = kItemMetadataState[state] ?? state;
+ info.push(span);
+ }
const shadowBlockInfo = itemMetadata?.['10'];
const blockedTimestampMicros = shadowBlockInfo?.['2'];
if (blockedTimestampMicros) {
const isBlocked = shadowBlockInfo?.['1'];
let span = document.createElement('span');
- span.textContent =
- isBlocked ? 'Shadow block active' : 'Shadow block no longer active';
+ span.textContent = chrome.i18n.getMessage(
+ 'inject_extrainfo_message_shadowblock' +
+ (isBlocked ? 'active' : 'notactive'));
if (isBlocked) span.classList.add('TWPT-extrainfo-bad');
info.push(span);
}
@@ -498,17 +546,17 @@
let label, labelClass;
switch (verdict) {
case 1: // LIVE_REVIEW_RELEVANT
- label = 'Relevant';
+ label = 'relevant';
labelClass = 'TWPT-extrainfo-good';
break;
case 2: // LIVE_REVIEW_OFF_TOPIC
- label = 'Off-topic';
+ label = 'offtopic';
labelClass = 'TWPT-extrainfo-bad';
break;
case 3: // LIVE_REVIEW_ABUSE
- label = 'Abuse';
+ label = 'abuse';
labelClass = 'TWPT-extrainfo-bad';
break;
}
@@ -519,7 +567,10 @@
let a = document.createElement('a');
a.href = 'https://support.google.com/s/community/user/' + reviewedBy;
a.classList.add(labelClass);
- a.textContent = 'Live review verdict: ' + label;
+ a.textContent = chrome.i18n.getMessage(
+ 'inject_extrainfo_message_livereviewverdict',
+ [chrome.i18n.getMessage(
+ 'inject_extrainfo_message_livereviewverdict_' + label)]);
let liveReviewTooltip = createPlainTooltip(a, date, false);
return [a, liveReviewTooltip];
}
@@ -542,9 +593,11 @@
const isTrending = thread?.['2']?.['25'];
const isTrendingAutoMarked = thread?.['39'];
if (isTrendingAutoMarked)
- info.push(document.createTextNode('Automatically marked as trending'));
+ info.push(document.createTextNode(
+ chrome.i18n.getMessage('inject_extrainfo_thread_autotrending')));
else if (isTrending)
- info.push(document.createTextNode('Trending'));
+ info.push(document.createTextNode(
+ chrome.i18n.getMessage('inject_extrainfo_thread_trending')));
const itemMetadata = thread?.['2']?.['12'];
const mdInfo = this.getMetadataInfo(itemMetadata);
@@ -797,7 +850,11 @@
const [badge, badgeTooltip] = createExtBadge();
let span = document.createElement('span');
- span.textContent = kItemMetadataState[state] ?? 'State ' + state;
+ span.textContent = chrome.i18n.getMessage(
+ 'inject_extrainfo_message_state_' +
+ kItemMetadataStateI18n[state]) ??
+ state;
+ span.title = kItemMetadataState[state] ?? state;
label.append(badge, span);
authorLine.prepend(label);
diff --git a/src/static/_locales/en/messages.json b/src/static/_locales/en/messages.json
index b78c8cc..12e39cd 100644
--- a/src/static/_locales/en/messages.json
+++ b/src/static/_locales/en/messages.json
@@ -397,6 +397,174 @@
"message": "Questions",
"description": "Label shown in the legend of the per-forum activity chart."
},
+ "inject_extrainfo_profile_abusecategory": {
+ "message": "Abuse category: $1",
+ "description": "Message shown in profiles when there is a policy violation."
+ },
+ "inject_extrainfo_profile_abusecategory_noviolation": {
+ "message": "No violation",
+ "description": "Abuse category"
+ },
+ "inject_extrainfo_profile_abusecategory_communitypolicy": {
+ "message": "Community policy violation",
+ "description": "Abuse category"
+ },
+ "inject_extrainfo_profile_abusecategory_legal": {
+ "message": "Legal violation",
+ "description": "Abuse category"
+ },
+ "inject_extrainfo_profile_abusecategory_csai": {
+ "message": "CSAI violation",
+ "description": "Abuse category"
+ },
+ "inject_extrainfo_profile_abusecategory_other": {
+ "message": "Other violation",
+ "description": "Abuse category"
+ },
+ "inject_extrainfo_profile_abuse_account": {
+ "message": "Account policy violation: $1",
+ "description": "Message shown in profiles when there is a policy violation."
+ },
+ "inject_extrainfo_profile_abuse_displayname": {
+ "message": "Display name policy violation: $1",
+ "description": "Message shown in profiles when there is a policy violation."
+ },
+ "inject_extrainfo_profile_abuse_avatar": {
+ "message": "Avatar policy violation: $1",
+ "description": "Message shown in profiles when there is a policy violation."
+ },
+ "inject_extrainfo_profile_appealsnum": {
+ "message": "Number of appeals: $1",
+ "description": "Message shown in profiles which states how many times the account has appealed the decision to ban their profile."
+ },
+ "inject_extrainfo_crs_used_singular": {
+ "message": "Used 1 time",
+ "description": "Shown alongside a canned response to state how many times it has been used."
+ },
+ "inject_extrainfo_crs_used_plural": {
+ "message": "Used $1 times",
+ "description": "Shown alongside a canned response to state how many times it has been used."
+ },
+ "inject_extrainfo_crs_lastused": {
+ "message": "Last used: $1",
+ "description": "Tooltip which states when a canned response was last used."
+ },
+ "inject_extrainfo_message_pendingstate": {
+ "message": "Only visible to badged users",
+ "description": "Label used in a thread or message when it is in the pending state (only visible to badged users)."
+ },
+ "inject_extrainfo_message_pendingstate_tooltip": {
+ "message": "Visible after $1",
+ "description": "Tooltip used for the label \"Only visible to badged users\" to state when the thread will become visible publicly."
+ },
+ "inject_extrainfo_message_state": {
+ "message": "State: $1",
+ "description": "Label used in a thread or message to show its state."
+ },
+ "inject_extrainfo_message_state_published": {
+ "message": "Published",
+ "description": "Thread/message state PUBLISHED."
+ },
+ "inject_extrainfo_message_state_draft": {
+ "message": "Draft",
+ "description": "Thread/message state DRAFT."
+ },
+ "inject_extrainfo_message_state_automated_abuse_take_down_hide": {
+ "message": "Take down hide automated abuse",
+ "description": "Thread/message state AUTOMATED_ABUSE_TAKE_DOWN_HIDE."
+ },
+ "inject_extrainfo_message_state_automated_abuse_take_down_delete": {
+ "message": "Take down delete automated abuse",
+ "description": "Thread/message state AUTOMATED_ABUSE_TAKE_DOWN_DELETE."
+ },
+ "inject_extrainfo_message_state_automated_abuse_reinstate": {
+ "message": "Reinstate automated abuse",
+ "description": "Thread/message state AUTOMATED_ABUSE_REINSTATE."
+ },
+ "inject_extrainfo_message_state_automated_off_topic_hide": {
+ "message": "Hide automated off-topic",
+ "description": "Thread/message state AUTOMATED_OFF_TOPIC_HIDE."
+ },
+ "inject_extrainfo_message_state_automated_flagged_pending_manual_review": {
+ "message": "Automated flagged (pending manual review)",
+ "description": "Thread/message state AUTOMATED_FLAGGED_PENDING_MANUAL_REVIEW."
+ },
+ "inject_extrainfo_message_state_user_flagged_pending_manual_review": {
+ "message": "User flagged (pending manual review)",
+ "description": "Thread/message state USER_FLAGGED_PENDING_MANUAL_REVIEW."
+ },
+ "inject_extrainfo_message_state_owner_deleted": {
+ "message": "Owner deleted",
+ "description": "Thread/message state OWNER_DELETED."
+ },
+ "inject_extrainfo_message_state_manual_take_down_hide": {
+ "message": "Manual take down hide",
+ "description": "Thread/message state MANUAL_TAKE_DOWN_HIDE."
+ },
+ "inject_extrainfo_message_state_manual_profile_take_down_suspend": {
+ "message": "Manual profile take down suspend",
+ "description": "Thread/message state MANUAL_PROFILE_TAKE_DOWN_SUSPEND."
+ },
+ "inject_extrainfo_message_state_manual_take_down_delete": {
+ "message": "Manual take down delete",
+ "description": "Thread/message state MANUAL_TAKE_DOWN_DELETE."
+ },
+ "inject_extrainfo_message_state_reinstate_profile_takedown": {
+ "message": "Reinstate profile takedown",
+ "description": "Thread/message state REINSTATE_PROFILE_TAKEDOWN."
+ },
+ "inject_extrainfo_message_state_reinstate_abuse_takedown": {
+ "message": "Reinstate abuse takedown",
+ "description": "Thread/message state REINSTATE_ABUSE_TAKEDOWN."
+ },
+ "inject_extrainfo_message_state_clear_off_topic": {
+ "message": "Clear off topic",
+ "description": "Thread/message state CLEAR_OFF_TOPIC."
+ },
+ "inject_extrainfo_message_state_confirm_off_topic": {
+ "message": "Confirm off topic",
+ "description": "Thread/message state CONFIRM_OFF_TOPIC."
+ },
+ "inject_extrainfo_message_state_googler_off_topic_hide": {
+ "message": "Googler off topic hide",
+ "description": "Thread/message state GOOGLER_OFF_TOPIC_HIDE."
+ },
+ "inject_extrainfo_message_state_expert_flagged_pending_manual_review": {
+ "message": "Expert flagged (pending manual review)",
+ "description": "Thread/message state EXPERT_FLAGGED_PENDING_MANUAL_REVIEW."
+ },
+ "inject_extrainfo_message_shadowblockactive": {
+ "message": "Shadow block active",
+ "description": "Label used in a thread or message when it has been shadow blocked and is thus hidden from view."
+ },
+ "inject_extrainfo_message_shadowblocknotactive": {
+ "message": "Shadow block no longer active",
+ "description": "Label used in a thread or message when it had been shadow blocked but it isn't active anymore."
+ },
+ "inject_extrainfo_message_livereviewverdict": {
+ "message": "Live review verdict: $1",
+ "description": "Label used in a thread or message to show what was the action taken when live reviewing it."
+ },
+ "inject_extrainfo_message_livereviewverdict_relevant": {
+ "message": "Relevant",
+ "description": "One of the actions of a live review."
+ },
+ "inject_extrainfo_message_livereviewverdict_offtopic": {
+ "message": "Off topic",
+ "description": "One of the actions of a live review."
+ },
+ "inject_extrainfo_message_livereviewverdict_abuse": {
+ "message": "Abuse",
+ "description": "One of the actions of a live review."
+ },
+ "inject_extrainfo_thread_autotrending": {
+ "message": "Automatically marked as trending",
+ "description": "Label used in a thread to show it has been automatically marked as trending."
+ },
+ "inject_extrainfo_thread_trending": {
+ "message": "Trending",
+ "description": "Label used in a thread to show it has been manually marked as trending."
+ },
"actionbadge_permissions_requested": {
"message": "Some features need additional permissions to work. Click to fix it.",
"description": "Tooltip for the extension icon when a feature is enabled but it needs several permissions to be granted."