feat(darklogo): port customDarkLogo (#20922)
This commit is contained in:
parent
4ca3084db5
commit
c48e93e00c
@ -8,6 +8,7 @@ case class MeetingSystemColumnsDbModel(
|
||||
loginUrl: Option[String],
|
||||
logoutUrl: Option[String],
|
||||
customLogoUrl: Option[String],
|
||||
customDarkLogoUrl: Option[String],
|
||||
bannerText: Option[String],
|
||||
bannerColor: Option[String],
|
||||
)
|
||||
@ -70,9 +71,10 @@ class MeetingDbTableDef(tag: Tag) extends Table[MeetingDbModel](tag, None, "meet
|
||||
val loginUrl = column[Option[String]]("loginUrl")
|
||||
val logoutUrl = column[Option[String]]("logoutUrl")
|
||||
val customLogoUrl = column[Option[String]]("customLogoUrl")
|
||||
val customDarkLogoUrl = column[Option[String]]("customDarkLogoUrl")
|
||||
val bannerText = column[Option[String]]("bannerText")
|
||||
val bannerColor = column[Option[String]]("bannerColor")
|
||||
val systemColumns = (loginUrl, logoutUrl, customLogoUrl, bannerText, bannerColor) <> (MeetingSystemColumnsDbModel.tupled, MeetingSystemColumnsDbModel.unapply)
|
||||
val systemColumns = (loginUrl, logoutUrl, customLogoUrl, customDarkLogoUrl, bannerText, bannerColor) <> (MeetingSystemColumnsDbModel.tupled, MeetingSystemColumnsDbModel.unapply)
|
||||
val createdTime = column[Long]("createdTime")
|
||||
val durationInSeconds = column[Int]("durationInSeconds")
|
||||
val endWhenNoModerator = column[Boolean]("endWhenNoModerator")
|
||||
@ -111,6 +113,10 @@ object MeetingDAO {
|
||||
case "" => None
|
||||
case logoUrl => Some(logoUrl)
|
||||
},
|
||||
customDarkLogoUrl = meetingProps.systemProps.customDarkLogoURL match {
|
||||
case "" => None
|
||||
case darkLogoUrl => Some(darkLogoUrl)
|
||||
},
|
||||
bannerText = meetingProps.systemProps.bannerText match {
|
||||
case "" => None
|
||||
case bannerText => Some(bannerText)
|
||||
|
@ -73,6 +73,7 @@ case class SystemProps(
|
||||
loginUrl: String,
|
||||
logoutUrl: String,
|
||||
customLogoURL: String,
|
||||
customDarkLogoURL: String,
|
||||
bannerText: String,
|
||||
bannerColor: String,
|
||||
)
|
||||
|
@ -37,6 +37,7 @@ public class ApiParams {
|
||||
public static final String MEETING_LAYOUT = "meetingLayout";
|
||||
public static final String IS_BREAKOUT = "isBreakout";
|
||||
public static final String LOGO = "logo";
|
||||
public static final String DARK_LOGO = "darklogo";
|
||||
public static final String LOGOUT_TIMER = "logoutTimer";
|
||||
public static final String LOGIN_URL = "loginURL";
|
||||
public static final String LOGOUT_URL = "logoutURL";
|
||||
|
@ -429,7 +429,7 @@ public class MeetingService implements MessageListener {
|
||||
m.getUserInactivityInspectTimerInMinutes(), m.getUserInactivityThresholdInMinutes(),
|
||||
m.getUserActivitySignResponseDelayInMinutes(), m.getEndWhenNoModerator(), m.getEndWhenNoModeratorDelayInMinutes(),
|
||||
m.getMuteOnStart(), m.getAllowModsToUnmuteUsers(), m.getAllowModsToEjectCameras(), m.getMeetingKeepEvents(),
|
||||
m.breakoutRoomsParams, m.lockSettingsParams, m.getLoginUrl(), m.getLogoutUrl(), m.getCustomLogoURL(),
|
||||
m.breakoutRoomsParams, m.lockSettingsParams, m.getLoginUrl(), m.getLogoutUrl(), m.getCustomLogoURL(), m.getCustomDarkLogoURL(),
|
||||
m.getBannerText(), m.getBannerColor(), m.getGroups(), m.getDisabledFeatures(), m.getNotifyRecordingIsOn(),
|
||||
m.getPresentationUploadExternalDescription(), m.getPresentationUploadExternalUrl(),
|
||||
m.getOverrideClientSettings());
|
||||
|
@ -105,7 +105,9 @@ public class ParamsProcessorUtil {
|
||||
private boolean defaultNotifyRecordingIsOn = false;
|
||||
private boolean defaultKeepEvents = false;
|
||||
private Boolean useDefaultLogo;
|
||||
private Boolean useDefaultDarkLogo;
|
||||
private String defaultLogoURL;
|
||||
private String defaultDarkLogoURL;
|
||||
private String defaultPresentationUploadExternalDescription = "";
|
||||
private String defaultPresentationUploadExternalUrl = "";
|
||||
|
||||
@ -830,6 +832,16 @@ public class ParamsProcessorUtil {
|
||||
meeting.setCustomLogoURL(this.getDefaultLogoURL());
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(params.get(ApiParams.DARK_LOGO))) {
|
||||
meeting.setCustomDarkLogoURL(params.get(ApiParams.DARK_LOGO));
|
||||
} else if (!StringUtils.isEmpty(params.get(ApiParams.LOGO))) {
|
||||
meeting.setCustomDarkLogoURL(params.get(ApiParams.LOGO));
|
||||
} else if (this.getUseDefaultDarkLogo()) {
|
||||
meeting.setCustomDarkLogoURL(this.getDefaultDarkLogoURL());
|
||||
} else if (!this.getUseDefaultDarkLogo() && this.getUseDefaultLogo()) {
|
||||
meeting.setCustomDarkLogoURL(this.getDefaultLogoURL());
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(params.get(ApiParams.COPYRIGHT))) {
|
||||
meeting.setCustomCopyright(params.get(ApiParams.COPYRIGHT));
|
||||
}
|
||||
@ -895,10 +907,18 @@ public class ParamsProcessorUtil {
|
||||
return useDefaultLogo;
|
||||
}
|
||||
|
||||
public Boolean getUseDefaultDarkLogo() {
|
||||
return useDefaultDarkLogo;
|
||||
}
|
||||
|
||||
public String getDefaultLogoURL() {
|
||||
return defaultLogoURL;
|
||||
}
|
||||
|
||||
public String getDefaultDarkLogoURL() {
|
||||
return defaultDarkLogoURL;
|
||||
}
|
||||
|
||||
public Boolean getAllowRequestsWithoutSession() {
|
||||
return allowRequestsWithoutSession;
|
||||
}
|
||||
@ -1262,10 +1282,19 @@ public class ParamsProcessorUtil {
|
||||
this.useDefaultLogo = value;
|
||||
}
|
||||
|
||||
public void setUseDefaultDarkLogo(Boolean value) {
|
||||
this.useDefaultDarkLogo = value;
|
||||
}
|
||||
|
||||
|
||||
public void setDefaultLogoURL(String url) {
|
||||
this.defaultLogoURL = url;
|
||||
}
|
||||
|
||||
public void setDefaultDarkLogoURL(String url) {
|
||||
this.defaultDarkLogoURL = url;
|
||||
}
|
||||
|
||||
public void setAllowRequestsWithoutSession(Boolean allowRequestsWithoutSession) {
|
||||
this.allowRequestsWithoutSession = allowRequestsWithoutSession;
|
||||
}
|
||||
|
@ -95,6 +95,7 @@ public class Meeting {
|
||||
private final List<String> breakoutRooms = new ArrayList<>();
|
||||
private ArrayList<Group> groups = new ArrayList<Group>();
|
||||
private String customLogoURL = "";
|
||||
private String customDarkLogoURL = "";
|
||||
private String customCopyright = "";
|
||||
private Boolean muteOnStart = false;
|
||||
private Boolean allowModsToUnmuteUsers = false;
|
||||
@ -643,10 +644,18 @@ public class Meeting {
|
||||
return customLogoURL;
|
||||
}
|
||||
|
||||
public String getCustomDarkLogoURL() {
|
||||
return customDarkLogoURL;
|
||||
}
|
||||
|
||||
public void setCustomLogoURL(String url) {
|
||||
customLogoURL = url;
|
||||
}
|
||||
|
||||
public void setCustomDarkLogoURL(String url) {
|
||||
customDarkLogoURL = url;
|
||||
}
|
||||
|
||||
public void setCustomCopyright(String copyright) {
|
||||
customCopyright = copyright;
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ public interface IBbbWebApiGWApp {
|
||||
String loginUrl,
|
||||
String logoutUrl,
|
||||
String customLogoURL,
|
||||
String customDarkLogoURL,
|
||||
String bannerText,
|
||||
String bannerColor,
|
||||
ArrayList<Group> groups,
|
||||
|
@ -157,6 +157,7 @@ class BbbWebApiGWApp(
|
||||
loginUrl: String,
|
||||
logoutUrl: String,
|
||||
customLogoURL: String,
|
||||
customDarkLogoURL: String,
|
||||
bannerText: String,
|
||||
bannerColor: String,
|
||||
groups: java.util.ArrayList[Group],
|
||||
@ -247,6 +248,7 @@ class BbbWebApiGWApp(
|
||||
},
|
||||
logoutUrl,
|
||||
customLogoURL,
|
||||
customDarkLogoURL,
|
||||
bannerText match {
|
||||
case t: String => t
|
||||
case _ => ""
|
||||
|
@ -33,6 +33,7 @@ create table "meeting" (
|
||||
"loginUrl" varchar(500),
|
||||
"logoutUrl" varchar(500),
|
||||
"customLogoUrl" varchar(500),
|
||||
"customDarkLogoUrl" varchar(500),
|
||||
"bannerText" text,
|
||||
"bannerColor" varchar(50),
|
||||
"createdTime" bigint,
|
||||
|
@ -161,6 +161,7 @@ select_permissions:
|
||||
- createdAt
|
||||
- createdTime
|
||||
- customLogoUrl
|
||||
- customDarkLogoUrl
|
||||
- disabledFeatures
|
||||
- durationInSeconds
|
||||
- endWhenNoModerator
|
||||
@ -190,6 +191,7 @@ select_permissions:
|
||||
- bannerColor
|
||||
- bannerText
|
||||
- customLogoUrl
|
||||
- customDarkLogoUrl
|
||||
- ended
|
||||
- endedAt
|
||||
- endedBy
|
||||
|
@ -2,6 +2,15 @@ import * as DarkReader from 'darkreader';
|
||||
import Styled from './styles';
|
||||
import logger from '/imports/startup/client/logger';
|
||||
import useMeeting from '../../core/hooks/useMeeting';
|
||||
import Storage from '/imports/ui/services/storage/session';
|
||||
|
||||
const CUSTOM_LOGO_URL_KEY = 'CustomLogoUrl';
|
||||
|
||||
const CUSTOM_DARK_LOGO_URL_KEY = 'CustomDarkLogoUrl';
|
||||
|
||||
const equalURLs = () => (
|
||||
Storage.getItem(CUSTOM_LOGO_URL_KEY) === Storage.getItem(CUSTOM_DARK_LOGO_URL_KEY)
|
||||
);
|
||||
|
||||
export function useMeetingIsBreakout() {
|
||||
const { data: meeting } = useMeeting((m) => ({
|
||||
@ -12,11 +21,17 @@ export function useMeetingIsBreakout() {
|
||||
}
|
||||
|
||||
export const setDarkTheme = (value) => {
|
||||
let invert = [Styled.DtfInvert];
|
||||
|
||||
if(equalURLs()) {
|
||||
invert = [Styled.DtfBrandingInvert];
|
||||
}
|
||||
|
||||
if (value && !DarkReader.isEnabled()) {
|
||||
DarkReader.enable(
|
||||
{ brightness: 100, contrast: 90 },
|
||||
{
|
||||
invert: [Styled.DtfInvert],
|
||||
invert,
|
||||
ignoreInlineStyle: [Styled.DtfCss],
|
||||
ignoreImageAnalysis: [Styled.DtfImages],
|
||||
},
|
||||
|
@ -23,6 +23,41 @@ const ActionsBar = styled.section`
|
||||
const Layout = styled(FlexColumn)``;
|
||||
|
||||
const DtfInvert = `
|
||||
body {
|
||||
background-color: var(--darkreader-neutral-background) !important;
|
||||
}
|
||||
header[id="Navbar"] {
|
||||
background-color: var(--darkreader-neutral-background) !important;
|
||||
}
|
||||
section[id="ActionsBar"] {
|
||||
background-color: var(--darkreader-neutral-background) !important;
|
||||
}
|
||||
select {
|
||||
border: 0.1rem solid #FFFFFF !important;
|
||||
}
|
||||
select[data-test="skipSlide"] {
|
||||
border: unset !important;
|
||||
}
|
||||
div[data-test="presentationContainer"] {
|
||||
background-color: var(--darkreader-neutral-background) !important;
|
||||
}
|
||||
select {
|
||||
border-top: unset !important;
|
||||
border-right: unset !important;
|
||||
border-left: unset !important;
|
||||
}
|
||||
.tl-container {
|
||||
background-color: var(--tl-background) !important;
|
||||
}
|
||||
#TD-Tools button, #TD-TopPanel-Undo, #TD-TopPanel-Redo, #TD-Styles {
|
||||
border-color: transparent !important;
|
||||
}
|
||||
[id="TD-StylesMenu"],
|
||||
[id="TD-Styles-Color-Container"],
|
||||
#connectionBars > div
|
||||
`;
|
||||
|
||||
const DtfBrandingInvert = `
|
||||
body {
|
||||
background-color: var(--darkreader-neutral-background) !important;
|
||||
}
|
||||
@ -73,6 +108,7 @@ export default {
|
||||
ActionsBar,
|
||||
Layout,
|
||||
DtfInvert,
|
||||
DtfBrandingInvert,
|
||||
DtfCss,
|
||||
DtfImages,
|
||||
};
|
||||
|
@ -42,6 +42,7 @@ interface PresenceManagerProps extends PresenceManagerContainerProps {
|
||||
bannerColor: string;
|
||||
bannerText: string;
|
||||
customLogoUrl: string;
|
||||
customDarkLogoUrl: string;
|
||||
loggedOut: boolean;
|
||||
guestStatus: string;
|
||||
guestLobbyMessage: string | null;
|
||||
@ -67,6 +68,7 @@ const PresenceManager: React.FC<PresenceManagerProps> = ({
|
||||
bannerColor,
|
||||
bannerText,
|
||||
customLogoUrl,
|
||||
customDarkLogoUrl,
|
||||
loggedOut,
|
||||
guestLobbyMessage,
|
||||
guestStatus,
|
||||
@ -112,6 +114,7 @@ const PresenceManager: React.FC<PresenceManagerProps> = ({
|
||||
extId,
|
||||
meetingName,
|
||||
customLogoUrl,
|
||||
customDarkLogoUrl,
|
||||
});
|
||||
}, []);
|
||||
|
||||
@ -227,6 +230,7 @@ const PresenceManagerContainer: React.FC<PresenceManagerContainerProps> = ({ chi
|
||||
bannerColor,
|
||||
bannerText,
|
||||
customLogoUrl,
|
||||
customDarkLogoUrl,
|
||||
} = userInfoData.meeting[0];
|
||||
const { extId, name: userName, userId } = userInfoData.user_current[0];
|
||||
|
||||
@ -250,6 +254,7 @@ const PresenceManagerContainer: React.FC<PresenceManagerContainerProps> = ({ chi
|
||||
bannerText={bannerText}
|
||||
loggedOut={loggedOut}
|
||||
customLogoUrl={customLogoUrl}
|
||||
customDarkLogoUrl={customDarkLogoUrl}
|
||||
guestLobbyMessage={guestStatusDetails?.guestLobbyMessage ?? null}
|
||||
positionInWaitingQueue={guestStatusDetails?.positionInWaitingQueue ?? null}
|
||||
guestStatus={guestStatus}
|
||||
|
@ -32,6 +32,7 @@ export interface GetUserInfoResponse {
|
||||
bannerColor: string;
|
||||
bannerText: string;
|
||||
customLogoUrl: string;
|
||||
customDarkLogoUrl: string;
|
||||
}>;
|
||||
user_current: Array<{
|
||||
extId: string;
|
||||
@ -49,6 +50,7 @@ query getUserInfo {
|
||||
bannerColor
|
||||
bannerText
|
||||
customLogoUrl
|
||||
customDarkLogoUrl
|
||||
}
|
||||
user_current {
|
||||
extId
|
||||
|
@ -23,6 +23,7 @@ export const setUserDataToSessionStorage = (userData: {
|
||||
extId: string,
|
||||
meetingName: string,
|
||||
customLogoUrl: string,
|
||||
customDarkLogoUrl: string,
|
||||
}) => {
|
||||
sessionStorage.setItem('meetingId', userData.meetingId);
|
||||
sessionStorage.setItem('userId', userData.userId);
|
||||
@ -32,6 +33,7 @@ export const setUserDataToSessionStorage = (userData: {
|
||||
sessionStorage.setItem('extId', userData.extId);
|
||||
sessionStorage.setItem('meetingName', userData.meetingName);
|
||||
Storage.setItem('CustomLogoUrl', userData.customLogoUrl);
|
||||
Storage.setItem('CustomDarkLogoUrl', userData.customDarkLogoUrl);
|
||||
};
|
||||
|
||||
export default {
|
||||
|
@ -8,12 +8,15 @@ import UserContentContainer from './user-list-content/container';
|
||||
const propTypes = {
|
||||
compact: PropTypes.bool,
|
||||
CustomLogoUrl: PropTypes.string,
|
||||
CustomDarkLogoUrl: PropTypes.string,
|
||||
DarkModeIsEnabled: PropTypes.bool,
|
||||
showBranding: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
compact: false,
|
||||
CustomLogoUrl: null,
|
||||
CustomDarkLogoUrl: null,
|
||||
};
|
||||
|
||||
class UserList extends PureComponent {
|
||||
@ -21,16 +24,19 @@ class UserList extends PureComponent {
|
||||
const {
|
||||
compact,
|
||||
CustomLogoUrl,
|
||||
CustomDarkLogoUrl,
|
||||
DarkModeIsEnabled,
|
||||
showBranding,
|
||||
} = this.props;
|
||||
const logoUrl = DarkModeIsEnabled ? CustomDarkLogoUrl : CustomLogoUrl;
|
||||
|
||||
return (
|
||||
<Styled.UserList>
|
||||
{
|
||||
showBranding
|
||||
&& !compact
|
||||
&& CustomLogoUrl
|
||||
? <CustomLogo CustomLogoUrl={CustomLogoUrl} /> : null
|
||||
&& logoUrl
|
||||
? <CustomLogo CustomLogoUrl={logoUrl} /> : null
|
||||
}
|
||||
<UserContentContainer compact={compact} />
|
||||
</Styled.UserList>
|
||||
|
@ -1,13 +1,19 @@
|
||||
import React from 'react';
|
||||
import getFromUserSettings from '/imports/ui/services/users-settings';
|
||||
import { isDarkThemeEnabled } from '/imports/ui/components/app/service';
|
||||
import UserList from './component';
|
||||
import { useStorageKey } from '../../services/storage/hooks';
|
||||
|
||||
const UserListContainer = (props) => {
|
||||
const CustomLogoUrl = useStorageKey('CustomLogoUrl', 'session');
|
||||
const CustomDarkLogoUrl = useStorageKey('CustomDarkLogoUrl', 'session');
|
||||
const DarkModeIsEnabled = isDarkThemeEnabled();
|
||||
|
||||
return (
|
||||
<UserList
|
||||
CustomLogoUrl={CustomLogoUrl}
|
||||
CustomDarkLogoUrl={CustomDarkLogoUrl}
|
||||
DarkModeIsEnabled={DarkModeIsEnabled}
|
||||
{...props}
|
||||
showBranding={getFromUserSettings('bbb_display_branding_area', window.meetingClientSettings.public.app.branding.displayBrandingArea)}
|
||||
/>
|
||||
|
@ -20,12 +20,18 @@ const STARTED_CHAT_LIST_KEY = 'startedChatList';
|
||||
|
||||
const CUSTOM_LOGO_URL_KEY = 'CustomLogoUrl';
|
||||
|
||||
const CUSTOM_DARK_LOGO_URL_KEY = 'CustomDarkLogoUrl';
|
||||
|
||||
export const setCustomLogoUrl = (path) => Storage.setItem(CUSTOM_LOGO_URL_KEY, path);
|
||||
|
||||
export const setCustomDarkLogoUrl = (path) => Storage.setItem(CUSTOM_DARK_LOGO_URL_KEY, path);
|
||||
|
||||
export const setModeratorOnlyMessage = (msg) => Storage.setItem('ModeratorOnlyMessage', msg);
|
||||
|
||||
const getCustomLogoUrl = () => Storage.getItem(CUSTOM_LOGO_URL_KEY);
|
||||
|
||||
const getCustomDarkLogoUrl = () => Storage.getItem(CUSTOM_DARK_LOGO_URL_KEY);
|
||||
|
||||
const sortByWhiteboardAccess = (a, b) => {
|
||||
const _a = a.whiteboardAccess;
|
||||
const _b = b.whiteboardAccess;
|
||||
@ -453,6 +459,7 @@ export default {
|
||||
isPublicChat,
|
||||
roving,
|
||||
getCustomLogoUrl,
|
||||
getCustomDarkLogoUrl,
|
||||
focusFirstDropDownItem,
|
||||
sortUsersByCurrent,
|
||||
UserJoinedMeetingAlert,
|
||||
|
@ -317,7 +317,9 @@ graphqlApiUrl=${bigbluebutton.web.serverURL}/api/rest
|
||||
sessionsCleanupDelayInMinutes=60
|
||||
|
||||
useDefaultLogo=false
|
||||
useDefaultDarkLogo=false
|
||||
defaultLogoURL=${bigbluebutton.web.serverURL}/images/logo.png
|
||||
defaultDarkLogoURL=${bigbluebutton.web.serverURL}/images/darklogo.png
|
||||
|
||||
# Allow requests without JSESSIONID to be handled (default = false)
|
||||
allowRequestsWithoutSession=false
|
||||
|
@ -144,7 +144,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<property name="graphqlWebsocketUrl" value="${graphqlWebsocketUrl}"/>
|
||||
<property name="graphqlApiUrl" value="${graphqlApiUrl}"/>
|
||||
<property name="useDefaultLogo" value="${useDefaultLogo}"/>
|
||||
<property name="useDefaultDarkLogo" value="${useDefaultDarkLogo}"/>
|
||||
<property name="defaultLogoURL" value="${defaultLogoURL}"/>
|
||||
<property name="defaultDarkLogoURL" value="${defaultDarkLogoURL}"/>
|
||||
<property name="allowRequestsWithoutSession" value="${allowRequestsWithoutSession}"/>
|
||||
<property name="defaultHttpSessionTimeout" value="${defaultHttpSessionTimeout}"/>
|
||||
<property name="defaultMeetingDuration" value="${defaultMeetingDuration}"/>
|
||||
|
Loading…
Reference in New Issue
Block a user