added role based coloring
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user