diff --git a/web/plugin.head.html b/web/plugin.head.html
index a76d350..efb04f8 100644
--- a/web/plugin.head.html
+++ b/web/plugin.head.html
@@ -2266,6 +2266,14 @@
.trim();
}
+ function normalizePoliticTalkDisplayName(value) {
+ return String(value || '')
+ .replace(/\(you\)/ig, '')
+ .replace(/\bmoderator\b/ig, '')
+ .replace(/\s+/g, ' ')
+ .trim();
+ }
+
function getPoliticTalkRoleMetadataFromElement(element) {
if (!element || !element.classList) {
return null;
@@ -2328,7 +2336,7 @@
|| getPoliticTalkGuestRoleMetadata();
}
- return getPoliticTalkGuestRoleMetadata();
+ return getPoliticTalkRoleMetadataFromElement(row) || getPoliticTalkGuestRoleMetadata();
}
function isPoliticTalkParticipantPaneAvatar(element) {
@@ -2408,33 +2416,155 @@
var target = element.querySelector('[data-testid="stage-display-name"], .displayname, [id$="_name"]');
var value = target ? target.textContent : element.textContent;
- return String(value || '').replace(/\s+/g, ' ').trim();
+ return normalizePoliticTalkDisplayName(value);
}
- function getPoliticTalkDominantSpeakerRoleMetadata(videospace, tiles) {
- var dominantName = getPoliticTalkVisibleDisplayName(
+ function getPoliticTalkDominantSpeakerDisplayNames(videospace) {
+ var largeVideoContainer = videospace && videospace.querySelector('#largeVideoContainer');
+
+ if (!largeVideoContainer) {
+ return [];
+ }
+
+ var selectors = [
+ '[data-testid="stage-display-name"]',
+ '#remotePresenceMessage',
+ '#remoteConnectionMessage',
+ '.displayname',
+ '[id$="_name"]',
+ '[class*="displayName"]',
+ '[class*="nameContainer"]',
+ '.presence-label-container',
+ '[class*="presenceLabel"]',
+ '[class*="PresenceLabel"]'
+ ].join(',');
+ var blockedLabels = [
+ 'aud',
+ 'meeting participants',
+ 'politictalk',
+ 'search participants'
+ ];
+ var names = [];
+
+ Array.prototype.slice.call(largeVideoContainer.querySelectorAll(selectors)).forEach(function(candidate) {
+ var text = normalizePoliticTalkDisplayName(candidate.textContent);
+ var normalized = normalizePoliticTalkText(text);
+
+ if (!text
+ || text.length > 80
+ || blockedLabels.indexOf(normalized) !== -1
+ || /^\d/.test(normalized)) {
+ return;
+ }
+
+ if (names.indexOf(text) === -1) {
+ names.push(text);
+ }
+ });
+
+ return names;
+ }
+
+ function getPoliticTalkDominantSpeakerNamesFromParticipantRows(videospace) {
+ var largeVideoContainer = videospace && videospace.querySelector('#largeVideoContainer');
+
+ if (!largeVideoContainer) {
+ return [];
+ }
+
+ var largeVideoText = normalizePoliticTalkText(largeVideoContainer.textContent);
+
+ if (!largeVideoText) {
+ return [];
+ }
+
+ return getPoliticTalkParticipantPaneRows().map(getPoliticTalkParticipantPaneDisplayName).filter(function(name, index, names) {
+ var normalizedName = normalizePoliticTalkText(name);
+
+ return normalizedName
+ && names.indexOf(name) === index
+ && largeVideoText.indexOf(normalizedName) !== -1;
+ });
+ }
+
+ function findPoliticTalkRoleMetadataByDisplayNames(names, videospace, tiles, thumbnails) {
+ var normalizedNames = (names || []).map(function(name) {
+ return normalizePoliticTalkText(normalizePoliticTalkDisplayName(name));
+ }).filter(Boolean);
+
+ if (!normalizedNames.length) {
+ return null;
+ }
+
+ var matchesName = function(value) {
+ return normalizedNames.indexOf(normalizePoliticTalkText(normalizePoliticTalkDisplayName(value))) !== -1;
+ };
+ var candidates = (tiles || []).concat(thumbnails || []);
+ var matchingTile = candidates.find(function(tile) {
+ return matchesName(getPoliticTalkVisibleDisplayName(tile));
+ });
+
+ if (matchingTile) {
+ return getPoliticTalkTileRoleMetadata(matchingTile)
+ || getPoliticTalkRoleMetadataFromElement(matchingTile)
+ || null;
+ }
+
+ var matchingRow = getPoliticTalkParticipantPaneRows().find(function(row) {
+ return matchesName(getPoliticTalkParticipantPaneDisplayName(row));
+ });
+
+ if (matchingRow) {
+ return getPoliticTalkParticipantPaneRoleMetadata(matchingRow, videospace, tiles, thumbnails)
+ || getPoliticTalkRoleMetadataFromElement(matchingRow)
+ || null;
+ }
+
+ return null;
+ }
+
+ function getPoliticTalkDominantSpeakerRoleMetadata(videospace, tiles, thumbnails) {
+ var dominantNames = getPoliticTalkDominantSpeakerDisplayNames(videospace).concat(
+ getPoliticTalkDominantSpeakerNamesFromParticipantRows(videospace)
+ );
+ var dominantName = dominantNames[0] || getPoliticTalkVisibleDisplayName(
videospace.querySelector('[data-testid="stage-display-name"]')
);
- var candidates = tiles || [];
+ var candidates = (tiles || []).concat(thumbnails || []);
+ var matchingMetadata = findPoliticTalkRoleMetadataByDisplayNames(
+ dominantNames.concat(dominantName ? [dominantName] : []),
+ videospace,
+ tiles,
+ thumbnails
+ );
+
+ if (matchingMetadata) {
+ return matchingMetadata;
+ }
if (dominantName) {
+ var normalizedDominantName = normalizePoliticTalkText(dominantName);
var matchingTile = candidates.find(function(tile) {
- return getPoliticTalkVisibleDisplayName(tile) === dominantName;
+ return normalizePoliticTalkText(getPoliticTalkVisibleDisplayName(tile)) === normalizedDominantName;
});
if (matchingTile) {
- return getPoliticTalkTileRoleMetadata(matchingTile) || getPoliticTalkGuestRoleMetadata();
+ return getPoliticTalkTileRoleMetadata(matchingTile)
+ || getPoliticTalkRoleMetadataFromElement(matchingTile)
+ || getPoliticTalkGuestRoleMetadata();
}
}
if (candidates.length === 1) {
- return getPoliticTalkTileRoleMetadata(candidates[0]) || getPoliticTalkGuestRoleMetadata();
+ return getPoliticTalkTileRoleMetadata(candidates[0])
+ || getPoliticTalkRoleMetadataFromElement(candidates[0])
+ || getPoliticTalkGuestRoleMetadata();
}
return getPoliticTalkLocalRoleMetadata();
}
- function applyPoliticTalkDominantSpeakerTheme(videospace, tiles, metadataOverride) {
+ function applyPoliticTalkDominantSpeakerTheme(videospace, tiles, thumbnails, metadataOverride) {
var avatar = videospace.querySelector('#dominantSpeakerAvatar');
var avatarContainer = videospace.querySelector('#dominantSpeakerAvatarContainer');
@@ -2442,7 +2572,7 @@
return;
}
- var metadata = metadataOverride || getPoliticTalkDominantSpeakerRoleMetadata(videospace, tiles);
+ var metadata = metadataOverride || getPoliticTalkDominantSpeakerRoleMetadata(videospace, tiles, thumbnails);
var roleWasApplied = applyPoliticTalkRoleToElement(avatar, metadata);
addPoliticTalkClass(avatar, 'politictalk-avatar-themed');
@@ -2458,6 +2588,11 @@
avatar.style.setProperty('--politictalk-avatar-background', fallbackColor);
avatar.style.setProperty('--politictalk-tile-border-color', fallbackColor);
}
+
+ var avatarColor = getPoliticTalkRoleColor(metadata && metadata.role);
+
+ setPoliticTalkImportantStyle(avatar, 'background', avatarColor);
+ setPoliticTalkImportantStyle(avatar, 'background-color', avatarColor);
}
function applyPoliticTalkAvatarThemeInContainer(container, metadata) {
@@ -2636,11 +2771,11 @@
var dominantName = getPoliticTalkVisibleDisplayName(
videospace.querySelector('[data-testid="stage-display-name"]')
);
- var dominantMetadata = getPoliticTalkDominantSpeakerRoleMetadata(videospace, tiles);
+ var dominantMetadata = getPoliticTalkDominantSpeakerRoleMetadata(videospace, tiles, thumbnails);
applyPoliticTalkLargeVideoLayout(videospace, tiles);
applyPoliticTalkTileLayout(videospace, tiles);
- applyPoliticTalkDominantSpeakerTheme(videospace, tiles, dominantMetadata);
+ applyPoliticTalkDominantSpeakerTheme(videospace, tiles, thumbnails, dominantMetadata);
tiles.forEach(function(tile) {
addPoliticTalkClass(tile, 'politictalk-themed-tile');