added role based coloring

This commit is contained in:
2026-06-01 21:51:40 +05:30
parent a27147328a
commit a6cb6b27c2

View File

@@ -15,7 +15,7 @@
--politictalk-stage-bottom-inset: 128px; --politictalk-stage-bottom-inset: 128px;
--politictalk-stage-side-inset: 8px; --politictalk-stage-side-inset: 8px;
--politictalk-stage-top-inset: 96px; --politictalk-stage-top-inset: 96px;
--politictalk-tile-border-color: rgba(179, 165, 228, 0.72); --politictalk-tile-border-color: #63477a;
--politictalk-toolbar-bottom-offset: 12px; --politictalk-toolbar-bottom-offset: 12px;
--politictalk-toolbar-mobile-scale: 0.96; --politictalk-toolbar-mobile-scale: 0.96;
} }
@@ -77,8 +77,28 @@
box-sizing: border-box !important; box-sizing: border-box !important;
} }
html:not(.politictalk-direct-access-blocked) #videospace .politictalk-role-individual {
--politictalk-avatar-background: #63477a;
--politictalk-tile-border-color: #63477a;
}
html:not(.politictalk-direct-access-blocked) #videospace .politictalk-role-organisation {
--politictalk-avatar-background: #937dc6;
--politictalk-tile-border-color: #937dc6;
}
html:not(.politictalk-direct-access-blocked) #videospace .politictalk-role-ordinary {
--politictalk-avatar-background: #b3a5e4;
--politictalk-tile-border-color: #b3a5e4;
}
html:not(.politictalk-direct-access-blocked) #videospace .politictalk-role-guest {
--politictalk-avatar-background: #63477a;
--politictalk-tile-border-color: #63477a;
}
html:not(.politictalk-direct-access-blocked) #videospace .politictalk-themed-tile::after { html:not(.politictalk-direct-access-blocked) #videospace .politictalk-themed-tile::after {
border: 2px solid var(--politictalk-tile-border-color, rgba(179, 165, 228, 0.72)) !important; border: 2px solid var(--politictalk-tile-border-color, #63477a) !important;
border-radius: 3px !important; border-radius: 3px !important;
bottom: 2px; bottom: 2px;
box-sizing: border-box !important; box-sizing: border-box !important;
@@ -724,6 +744,20 @@
<script> <script>
(function() { (function() {
var PARALLEL_GLOBE_URL = 'https://parallelglobe.io'; var PARALLEL_GLOBE_URL = 'https://parallelglobe.io';
var POLITICTALK_ROLE_COLORS = {
guest: '#63477a',
individual: '#63477a',
organisation: '#937dc6',
ordinary: '#b3a5e4'
};
var POLITICTALK_ROLE_CLASS_NAMES = [
'politictalk-role-guest',
'politictalk-role-individual',
'politictalk-role-organisation',
'politictalk-role-ordinary'
];
var politicTalkParticipantRolesByEndpointId = {};
var politicTalkParticipantRolesByUserId = {};
disablePoliticTalkPwaInstallPrompt(); disablePoliticTalkPwaInstallPrompt();
@@ -1139,6 +1173,290 @@
|| readRoomSessionValue('title'); || readRoomSessionValue('title');
} }
function normalizePoliticTalkRole(value) {
var role = String(value || '')
.trim()
.toLowerCase()
.replace(/_/g, '-')
.replace(/\s+/g, '-');
if (role === 'political-voice' || role === 'politicalvoice') {
return 'individual';
}
if (role === 'org' || role === 'organization') {
return 'organisation';
}
if (role === 'parallel-citizen' || role === 'parallelcitizen' || role === 'citizen') {
return 'ordinary';
}
if (role === 'email-invite' || role === 'invitee' || role === 'invited' || role === 'guest') {
return 'guest';
}
if (role === 'individual' || role === 'organisation' || role === 'ordinary') {
return role;
}
return '';
}
function getPoliticTalkRoleColor(role) {
return POLITICTALK_ROLE_COLORS[normalizePoliticTalkRole(role)] || POLITICTALK_ROLE_COLORS.guest;
}
function getPoliticTalkJwtUserContext() {
var payload = getPoliticTalkJwtPayload();
return payload && payload.context && payload.context.user
? payload.context.user
: {};
}
function getPoliticTalkLocalRoleMetadata() {
var user = getPoliticTalkJwtUserContext();
var role = normalizePoliticTalkRole(
user.politictalkRole
|| user.platformRole
|| user.politicalRole
|| user.role
) || 'guest';
var userId = String(user.id || '').trim();
return {
color: getPoliticTalkRoleColor(role),
role: role,
userId: userId,
userType: String(user.politictalkUserType || user.userType || '').trim()
};
}
function rememberPoliticTalkParticipantRole(metadata, endpointId) {
if (!metadata) {
return false;
}
var role = normalizePoliticTalkRole(metadata.role || metadata.politictalkRole || metadata.platformRole);
if (!role) {
return false;
}
var normalizedMetadata = {
color: getPoliticTalkRoleColor(role),
role: role,
userId: String(metadata.userId || metadata.id || '').trim(),
userType: String(metadata.userType || metadata.politictalkUserType || '').trim()
};
var normalizedEndpointId = String(endpointId || metadata.endpointId || metadata.participantId || '').trim();
if (normalizedEndpointId) {
politicTalkParticipantRolesByEndpointId[normalizedEndpointId] = normalizedMetadata;
}
if (normalizedMetadata.userId) {
politicTalkParticipantRolesByUserId[normalizedMetadata.userId] = normalizedMetadata;
}
return true;
}
function getPoliticTalkConferenceRoom() {
var conference = window.APP && window.APP.conference;
return conference && (conference._room || conference.room || conference.conference);
}
function getPoliticTalkEndpointIdFromValue(value) {
if (!value) {
return '';
}
if (typeof value === 'string') {
return value;
}
try {
if (typeof value.getId === 'function') {
return String(value.getId() || '');
}
} catch (error) {
return '';
}
return String(value.id || value._id || value.participantId || '').trim();
}
function getPoliticTalkLocalEndpointId() {
var room = getPoliticTalkConferenceRoom();
var conference = window.APP && window.APP.conference;
try {
if (room && typeof room.myUserId === 'function') {
return String(room.myUserId() || '');
}
if (room && typeof room.getMyUserId === 'function') {
return String(room.getMyUserId() || '');
}
if (conference && typeof conference.getMyUserId === 'function') {
return String(conference.getMyUserId() || '');
}
} catch (error) {
return '';
}
return '';
}
function parsePoliticTalkRoleMetadata(value) {
if (!value) {
return null;
}
if (typeof value === 'string') {
try {
return JSON.parse(value);
} catch (error) {
return null;
}
}
if (value.type === 'politictalk-role') {
return value.data || value;
}
if (value.value) {
return parsePoliticTalkRoleMetadata(value.value) || value.attributes || null;
}
if (value.attributes && (value.attributes.role || value.attributes.politictalkRole)) {
return value.attributes;
}
if (value.role || value.politictalkRole || value.platformRole) {
return value;
}
return null;
}
function handlePoliticTalkRoleMetadataMessage(first, second) {
var metadata = parsePoliticTalkRoleMetadata(first) || parsePoliticTalkRoleMetadata(second);
var endpointId = getPoliticTalkEndpointIdFromValue(first) || getPoliticTalkEndpointIdFromValue(second);
if (rememberPoliticTalkParticipantRole(metadata, endpointId)) {
window.cancelAnimationFrame(window.politicTalkRoleTileFrame);
window.politicTalkRoleTileFrame = window.requestAnimationFrame(applyPoliticTalkTileTheme);
}
}
function attachPoliticTalkRoleMetadataListeners(room) {
if (!room || window.politicTalkRoleMetadataRoom === room) {
return;
}
window.politicTalkRoleMetadataRoom = room;
try {
if (typeof room.addCommandListener === 'function') {
room.addCommandListener('politictalk-role', handlePoliticTalkRoleMetadataMessage);
}
} catch (error) {
// Role colours are cosmetic; keep the room running if the Jitsi internals differ.
}
try {
if (typeof room.on === 'function') {
var events = window.JitsiMeetJS && window.JitsiMeetJS.events && window.JitsiMeetJS.events.conference;
var endpointEvents = [
events && events.ENDPOINT_MESSAGE_RECEIVED,
'endpoint_message_received'
].filter(Boolean);
endpointEvents.forEach(function(eventName, index) {
if (endpointEvents.indexOf(eventName) !== index) {
return;
}
room.on(eventName, handlePoliticTalkRoleMetadataMessage);
});
}
} catch (error) {
// Ignore API differences across Jitsi versions.
}
}
function publishPoliticTalkRoleMetadata() {
if (directAccessBlocked) {
return;
}
var metadata = getPoliticTalkLocalRoleMetadata();
var endpointId = getPoliticTalkLocalEndpointId();
var room = getPoliticTalkConferenceRoom();
rememberPoliticTalkParticipantRole(metadata, endpointId);
attachPoliticTalkRoleMetadataListeners(room);
if (!room) {
return;
}
var payload = {
color: metadata.color,
endpointId: endpointId,
role: metadata.role,
type: 'politictalk-role',
userId: metadata.userId,
userType: metadata.userType
};
try {
if (typeof room.sendCommandOnce === 'function') {
room.sendCommandOnce('politictalk-role', {
attributes: payload,
value: JSON.stringify(payload)
});
} else if (typeof room.sendCommand === 'function') {
room.sendCommand('politictalk-role', {
attributes: payload,
value: JSON.stringify(payload)
});
}
} catch (error) {
// Endpoint messages below are a fallback for Jitsi builds without custom commands.
}
try {
if (typeof room.sendEndpointMessage === 'function') {
room.sendEndpointMessage('', payload);
}
} catch (error) {
// Nothing else to do; local styling still works from the JWT.
}
}
function mountPoliticTalkRoleMetadataSync() {
if (directAccessBlocked) {
return;
}
publishPoliticTalkRoleMetadata();
if (window.politicTalkRoleMetadataInterval) {
return;
}
window.politicTalkRoleMetadataInterval = window.setInterval(function() {
publishPoliticTalkRoleMetadata();
applyPoliticTalkTileTheme();
}, 5000);
}
function isPoliticTalkHost() { function isPoliticTalkHost() {
var payload = getPoliticTalkJwtPayload(); var payload = getPoliticTalkJwtPayload();
var user = payload && payload.context && payload.context.user; var user = payload && payload.context && payload.context.user;
@@ -1494,6 +1812,72 @@
return Math.max(180, availableHeight); return Math.max(180, availableHeight);
} }
function getPoliticTalkTileEndpointId(tile) {
if (!tile) {
return '';
}
var tileId = String(tile.id || '');
if (tileId === 'localVideo_container') {
return getPoliticTalkLocalEndpointId();
}
var match = tileId.match(/^(?:participant_|remoteVideo_)(.+)$/);
if (match) {
return match[1];
}
return String(
tile.getAttribute('data-participant-id')
|| tile.getAttribute('data-endpoint-id')
|| ''
).trim();
}
function getPoliticTalkTileRoleMetadata(tile) {
var localMetadata = getPoliticTalkLocalRoleMetadata();
var endpointId = getPoliticTalkTileEndpointId(tile);
if (tile && tile.id === 'localVideo_container') {
return localMetadata;
}
if (endpointId && politicTalkParticipantRolesByEndpointId[endpointId]) {
return politicTalkParticipantRolesByEndpointId[endpointId];
}
var localEndpointId = getPoliticTalkLocalEndpointId();
if (endpointId && localEndpointId && endpointId === localEndpointId) {
return localMetadata;
}
return null;
}
function applyPoliticTalkRoleToTile(tile, metadata) {
if (!tile || !tile.classList) {
return;
}
POLITICTALK_ROLE_CLASS_NAMES.forEach(function(className) {
tile.classList.remove(className);
});
if (!metadata || !normalizePoliticTalkRole(metadata.role)) {
return;
}
var role = normalizePoliticTalkRole(metadata.role);
var color = getPoliticTalkRoleColor(role);
tile.classList.add('politictalk-role-' + role);
tile.style.setProperty('--politictalk-avatar-background', color);
tile.style.setProperty('--politictalk-tile-border-color', color);
}
function applyPoliticTalkTileLayout(videospace, tiles) { function applyPoliticTalkTileLayout(videospace, tiles) {
if (!videospace || !tiles.length) { if (!videospace || !tiles.length) {
return; return;
@@ -1578,6 +1962,7 @@
tiles.forEach(function(tile) { tiles.forEach(function(tile) {
addPoliticTalkClass(tile, 'politictalk-themed-tile'); addPoliticTalkClass(tile, 'politictalk-themed-tile');
applyPoliticTalkRoleToTile(tile, getPoliticTalkTileRoleMetadata(tile));
tile.querySelectorAll('div, span').forEach(function(candidate) { tile.querySelectorAll('div, span').forEach(function(candidate) {
if (isPoliticTalkAvatarShell(candidate, tile)) { if (isPoliticTalkAvatarShell(candidate, tile)) {
@@ -1985,6 +2370,7 @@
mountHostHangupPolicy(); mountHostHangupPolicy();
mountMobileToolbarPositioning(); mountMobileToolbarPositioning();
mountPoliticTalkStageBrandInset(); mountPoliticTalkStageBrandInset();
mountPoliticTalkRoleMetadataSync();
mountPoliticTalkTileTheme(); mountPoliticTalkTileTheme();
mountPoliticTalkModerationNotificationPolicy(); mountPoliticTalkModerationNotificationPolicy();
mountPoliticTalkAudioOnlyUiPolicy(); mountPoliticTalkAudioOnlyUiPolicy();
@@ -1997,6 +2383,7 @@
mountHostHangupPolicy(); mountHostHangupPolicy();
mountMobileToolbarPositioning(); mountMobileToolbarPositioning();
mountPoliticTalkStageBrandInset(); mountPoliticTalkStageBrandInset();
mountPoliticTalkRoleMetadataSync();
mountPoliticTalkTileTheme(); mountPoliticTalkTileTheme();
mountPoliticTalkModerationNotificationPolicy(); mountPoliticTalkModerationNotificationPolicy();
mountPoliticTalkAudioOnlyUiPolicy(); mountPoliticTalkAudioOnlyUiPolicy();