From beca90965eee9159023ca32ae7c419b694baafc6 Mon Sep 17 00:00:00 2001 From: Guilherme Leme Date: Thu, 26 Sep 2024 15:01:18 -0300 Subject: [PATCH 1/5] [lms-plugin-adaptation] added title actions and refactored some logic related to extensible-area setters --- .../ui/components/common/menu/component.jsx | 24 ++++++++++--- .../ui/components/common/menu/styles.js | 34 +++++++++++++++++-- .../user-list-participants/page/component.tsx | 13 ++++++- .../user-actions/component.tsx | 26 +++++++------- 4 files changed, 77 insertions(+), 20 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx b/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx index 1479cb46d1..80321018cb 100644 --- a/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx @@ -102,7 +102,8 @@ class BBBMenu extends React.Component { return actions?.map(a => { const { dataTest, label, onClick, key, disabled, - description, selected, textColor, isToggle, loading } = a; + description, selected, textColor, isToggle, loading, + isTitle, titleActions } = a; const emojiSelected = key?.toLowerCase()?.includes(selectedEmoji?.toLowerCase()); let customStyles = { @@ -146,7 +147,7 @@ class BBBMenu extends React.Component { }}> {a.icon ? : null} - {label} + {label} {description &&
{`${description}${selected ? ` - ${intl.formatMessage(intlMessages.active)}` : ''}`}
} {a.iconRight ? : null}
@@ -156,10 +157,25 @@ class BBBMenu extends React.Component { - + {a.icon ? : null} - {label} + {label} {a.iconRight ? : null} + {(isTitle && titleActions?.length > 0) ? ( + titleActions.map((item) => ( + + )) + ) : null} ), diff --git a/bigbluebutton-html5/imports/ui/components/common/menu/styles.js b/bigbluebutton-html5/imports/ui/components/common/menu/styles.js index 6f5055f81c..e4d7c59b44 100644 --- a/bigbluebutton-html5/imports/ui/components/common/menu/styles.js +++ b/bigbluebutton-html5/imports/ui/components/common/menu/styles.js @@ -2,8 +2,14 @@ import styled from 'styled-components'; import Button from "/imports/ui/components/common/button/component"; import Icon from '/imports/ui/components/common/icon/component'; import MenuItem from "@mui/material/MenuItem"; -import { colorWhite, colorPrimary } from '/imports/ui/stylesheets/styled-components/palette'; -import { fontSizeLarge } from '/imports/ui/stylesheets/styled-components/typography'; +import { + colorWhite, + colorPrimary, +} from '/imports/ui/stylesheets/styled-components/palette'; +import { + fontSizeLarge, + headingsFontWeight, +} from '/imports/ui/stylesheets/styled-components/typography'; import { mediumUp } from '/imports/ui/stylesheets/styled-components/breakpoints'; import Menu from "@mui/material/Menu"; @@ -31,16 +37,37 @@ const MenuItemWrapper = styled.div` flex-flow: row; width: 100%; align-items: center; + ${({ hasSpaceBetween }) => hasSpaceBetween && ` + justify-content: space-between; + `} +`; + +const TitleAction = styled(Button)` + z-index: 3; + margin-left: .1rem; + & > span:first-child { + margin: 0; + padding: 0; + } `; const Option = styled.div` line-height: 1; margin-right: 1.65rem; - margin-left: .5rem; + ${({ hasIcon }) => hasIcon && ` + margin-left: .5rem; + `} white-space: normal; overflow-wrap: anywhere; padding: .1rem 0; + ${({ isTitle }) => isTitle && ` + margin-left: .1rem; + padding: .1rem 0 0 0; + font-size: 1.1rem; + font-weight: ${headingsFontWeight}; + `} + [dir="rtl"] & { margin-right: .5rem; margin-left: 1.65rem; @@ -145,6 +172,7 @@ const SkeletonWrapper = styled.span` `; export default { + TitleAction, MenuWrapper, MenuItemWrapper, Option, diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/page/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/page/component.tsx index c74c0600ad..dfd9692497 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/page/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/page/component.tsx @@ -1,4 +1,5 @@ -import React, { useEffect, useRef } from 'react'; +import React, { useContext, useEffect, useRef } from 'react'; +import * as PluginSdk from 'bigbluebutton-html-plugin-sdk'; import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; import { MEETING_PERMISSIONS_SUBSCRIPTION } from '../queries'; import { setLocalUserList, useLoadedUserList } from '/imports/ui/core/hooks/useLoadedUserList'; @@ -13,6 +14,7 @@ import ListItem from '../list-item/component'; import { layoutSelect } from '/imports/ui/components/layout/context'; import { Layout } from '/imports/ui/components/layout/layoutTypes'; import SkeletonUserListItem from '../list-item/skeleton/component'; +import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context'; interface UserListParticipantsContainerProps { index: number; @@ -36,6 +38,14 @@ const UsersListParticipantsPage: React.FC = ({ }) => { const [openUserAction, setOpenUserAction] = React.useState(null); const isRTL = layoutSelect((i: Layout) => i.isRTL); + const { pluginsExtensibleAreasAggregatedState } = useContext(PluginsContext); + let userListDropdownItems = [] as PluginSdk.UserListDropdownInterface[]; + if (pluginsExtensibleAreasAggregatedState.userListDropdownItems) { + userListDropdownItems = [ + ...pluginsExtensibleAreasAggregatedState.userListDropdownItems, + ]; + } + return ( <> { @@ -49,6 +59,7 @@ const UsersListParticipantsPage: React.FC = ({ usersPolicies={meeting.usersPolicies} isBreakout={meeting.isBreakout} pageId={pageId} + userListDropdownItems={userListDropdownItems} open={user.userId === openUserAction} setOpenUserAction={setOpenUserAction} > diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/component.tsx index 11a131d865..651839ac01 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/component.tsx @@ -1,4 +1,4 @@ -import React, { useState, useContext } from 'react'; +import React, { useState } from 'react'; import { User } from '/imports/ui/Types/user'; import { LockSettings, UsersPolicies } from '/imports/ui/Types/meeting'; import { useIntl, defineMessages } from 'react-intl'; @@ -34,7 +34,6 @@ import ConfirmationModal from '/imports/ui/components/common/modal/confirmation/ import BBBMenu from '/imports/ui/components/common/menu/component'; import { setPendingChat } from '/imports/ui/core/local-states/usePendingChat'; -import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context'; import Styled from './styles'; import { useMutation, useLazyQuery } from '@apollo/client'; import { CURRENT_PAGE_WRITERS_QUERY } from '/imports/ui/components/whiteboard/queries'; @@ -43,6 +42,7 @@ import useToggleVoice from '/imports/ui/components/audio/audio-graphql/hooks/use import useWhoIsUnmuted from '/imports/ui/core/hooks/useWhoIsUnmuted'; interface UserActionsProps { + userListDropdownItems: PluginSdk.UserListDropdownInterface[]; user: User; currentUser: User; lockSettings: LockSettings; @@ -200,6 +200,7 @@ const UserActions: React.FC = ({ isBreakout, children, pageId, + userListDropdownItems, open, setOpenUserAction, }) => { @@ -251,8 +252,6 @@ const UserActions: React.FC = ({ } }; - const { pluginsExtensibleAreasAggregatedState } = useContext(PluginsContext); - const { data: unmutedUsers } = useWhoIsUnmuted(); const isMuted = !unmutedUsers[user.userId]; @@ -283,13 +282,6 @@ const UserActions: React.FC = ({ const userChatLocked = user.userLockSettings?.disablePublicChat; - let userListDropdownItems = [] as PluginSdk.UserListDropdownInterface[]; - if (pluginsExtensibleAreasAggregatedState.userListDropdownItems) { - userListDropdownItems = [ - ...pluginsExtensibleAreasAggregatedState.userListDropdownItems, - ]; - } - const userDropdownItems = userListDropdownItems.filter( (item: PluginSdk.UserListDropdownInterface) => (user?.userId === item?.userId), ); @@ -325,8 +317,18 @@ const UserActions: React.FC = ({ }); } }; - + const t = userDropdownItems.filter( + (item: PluginSdk.UserListDropdownInterface) => ( + item?.type === UserListDropdownItemType.TITLE_ACTION), + ); const dropdownOptions = [ + { + allowed: true, + key: 'userName', + label: user.name, + titleActions: t, + isTitle: true, + }, ...makeDropdownPluginItem(userDropdownItems.filter( (item: PluginSdk.UserListDropdownInterface) => (item?.type === UserListDropdownItemType.INFORMATION), )), From 7cc90c17349a02a9de9575d91893901acf460f0f Mon Sep 17 00:00:00 2001 From: Guilherme Leme Date: Fri, 27 Sep 2024 14:48:05 -0300 Subject: [PATCH 2/5] [lms-plugin-adaptation] Added new genericContentInformation along with refactor of fixedContentInformation for userListDropodownItem. --- .../ui/components/common/menu/component.jsx | 44 ++++++++++++------- .../generic-content-item/component.tsx | 13 ++++-- .../generic-content-item/types.ts | 1 + .../user-actions/component.tsx | 42 +++++++++++++----- 4 files changed, 67 insertions(+), 33 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx b/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx index 80321018cb..a64e4b3d1f 100644 --- a/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx @@ -6,6 +6,7 @@ import Icon from "/imports/ui/components/common/icon/component"; import { SMALL_VIEWPORT_BREAKPOINT } from '/imports/ui/components/layout/enums'; import KEY_CODES from '/imports/utils/keyCodes'; import MenuSkeleton from './skeleton'; +import GenericContentItem from '/imports/ui/components/generic-content/generic-content-item/component'; import Styled from './styles'; const intlMessages = defineMessages({ @@ -103,7 +104,7 @@ class BBBMenu extends React.Component { return actions?.map(a => { const { dataTest, label, onClick, key, disabled, description, selected, textColor, isToggle, loading, - isTitle, titleActions } = a; + isTitle, titleActions, contentFunction } = a; const emojiSelected = key?.toLowerCase()?.includes(selectedEmoji?.toLowerCase()); let customStyles = { @@ -160,22 +161,31 @@ class BBBMenu extends React.Component { - {a.icon ? : null} - {label} - {a.iconRight ? : null} - {(isTitle && titleActions?.length > 0) ? ( - titleActions.map((item) => ( - - )) - ) : null} + {!contentFunction ? ( + <> + {a.icon ? : null} + {label} + {a.iconRight ? : null} + {(isTitle && titleActions?.length > 0) ? ( + titleActions.map((item) => ( + + )) + ) : null} + + ) : ( + + )} ), diff --git a/bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/component.tsx b/bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/component.tsx index 4304bc57a7..926c0de36c 100644 --- a/bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/component.tsx @@ -4,6 +4,7 @@ import { GenericContentItemProps } from './types'; const GenericContentItem: React.FC = (props) => { const { renderFunction, + width, } = props; const elementRef = useRef(null); @@ -13,12 +14,16 @@ const GenericContentItem: React.FC = (props) => { } }, [elementRef]); + const style: React.CSSProperties = { + height: '100%', + overflow: 'hidden', + }; + if (width) { + style.width = width; + } return (
); diff --git a/bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/types.ts b/bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/types.ts index cce3db6ecb..86426fde7d 100644 --- a/bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/types.ts +++ b/bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/types.ts @@ -1,3 +1,4 @@ export interface GenericContentItemProps { renderFunction: (element: HTMLElement) => void; + width?: string; } diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/component.tsx index 651839ac01..ce433c6a44 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/component.tsx @@ -56,14 +56,15 @@ interface UserActionsProps { interface DropdownItem { key: string; - label: string | undefined; - icon: string | undefined; - tooltip: string | undefined; - allowed: boolean | undefined; - iconRight: string | undefined; - textColor: string | undefined; - isSeparator: boolean | undefined; - onClick: (() => void) | undefined; + label?: string; + icon?: string; + tooltip?: string; + allowed?: boolean; + iconRight?: string; + textColor?: string; + isSeparator?: boolean; + contentFunction?: ((element: HTMLElement) => void); + onClick?: (() => void); } interface Writer { @@ -171,8 +172,8 @@ const makeDropdownPluginItem: ( returnValue.onClick = dropdownButton.onClick; break; } - case UserListDropdownItemType.INFORMATION: { - const dropdownButton = userDropdownItem as PluginSdk.UserListDropdownInformation; + case UserListDropdownItemType.FIXED_CONTENT_INFORMATION: { + const dropdownButton = userDropdownItem as PluginSdk.UserListDropdownFixedContentInformation; returnValue.label = dropdownButton.label; returnValue.icon = dropdownButton.icon; returnValue.iconRight = dropdownButton.iconRight; @@ -180,6 +181,12 @@ const makeDropdownPluginItem: ( returnValue.allowed = dropdownButton.allowed; break; } + case UserListDropdownItemType.GENERIC_CONTENT_INFORMATION: { + const dropdownButton = userDropdownItem as PluginSdk.UserListDropdownGenericContentInformation; + returnValue.allowed = dropdownButton.allowed; + returnValue.contentFunction = dropdownButton.contentFunction; + break; + } case UserListDropdownItemType.SEPARATOR: { returnValue.allowed = true; returnValue.isSeparator = true; @@ -330,7 +337,12 @@ const UserActions: React.FC = ({ isTitle: true, }, ...makeDropdownPluginItem(userDropdownItems.filter( - (item: PluginSdk.UserListDropdownInterface) => (item?.type === UserListDropdownItemType.INFORMATION), + (item: PluginSdk.UserListDropdownInterface) => ( + item?.type === UserListDropdownItemType.FIXED_CONTENT_INFORMATION + || item?.type === UserListDropdownItemType.GENERIC_CONTENT_INFORMATION + || (item?.type === UserListDropdownItemType.SEPARATOR + && (item as PluginSdk.UserListDropdownSeparator)?.position + === PluginSdk.UserListDropdownSeparatorPosition.BEFORE)), )), { allowed: user.cameras.length > 0 @@ -542,7 +554,13 @@ const UserActions: React.FC = ({ dataTest: 'ejectCamera', }, ...makeDropdownPluginItem(userDropdownItems.filter( - (item: PluginSdk.UserListDropdownInterface) => (item?.type !== UserListDropdownItemType.INFORMATION), + (item: PluginSdk.UserListDropdownInterface) => ( + item?.type !== UserListDropdownItemType.FIXED_CONTENT_INFORMATION + && item?.type !== UserListDropdownItemType.GENERIC_CONTENT_INFORMATION + && !(item?.type === UserListDropdownItemType.SEPARATOR + && (item as PluginSdk.UserListDropdownSeparator)?.position + === PluginSdk.UserListDropdownSeparatorPosition.BEFORE) + ), )), ]; From fd5dcb804bf59a31dfe9ffbaaf7c791ec1b5b243 Mon Sep 17 00:00:00 2001 From: Guilherme Leme Date: Mon, 30 Sep 2024 20:15:02 -0300 Subject: [PATCH 3/5] [lms-plugin-adaptation] enhanced css style --- .../imports/ui/components/common/menu/component.jsx | 2 ++ .../imports/ui/components/common/menu/styles.js | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx b/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx index a64e4b3d1f..dce5673a53 100644 --- a/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx @@ -157,6 +157,8 @@ class BBBMenu extends React.Component { (!onClick && !a.isSeparator) && ( ((isGenericContent) ? ` + padding: 0 16px; + ` : ` + padding: 12px 16px; + `)} + ${({ isTitle }) => (isTitle) && ` + min-width: 15rem; + padding: 12px 16px 8px 16px; + `} margin: 0; `; From 614e64d459c4c6de366cf0f91b853eba20975e8c Mon Sep 17 00:00:00 2001 From: Guilherme Leme Date: Tue, 1 Oct 2024 15:00:01 -0300 Subject: [PATCH 4/5] [lms-plugin-adaptation] update sdk --- bigbluebutton-html5/package-lock.json | 8 ++++---- bigbluebutton-html5/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bigbluebutton-html5/package-lock.json b/bigbluebutton-html5/package-lock.json index 20b32a775f..14c38f8984 100644 --- a/bigbluebutton-html5/package-lock.json +++ b/bigbluebutton-html5/package-lock.json @@ -27,7 +27,7 @@ "autoprefixer": "^10.4.4", "axios": "^1.7.4", "babel-runtime": "~6.26.0", - "bigbluebutton-html-plugin-sdk": "0.0.58", + "bigbluebutton-html-plugin-sdk": "0.0.59", "bowser": "^2.11.0", "browser-bunyan": "^1.8.0", "classnames": "^2.2.6", @@ -5822,9 +5822,9 @@ } }, "node_modules/bigbluebutton-html-plugin-sdk": { - "version": "0.0.58", - "resolved": "https://registry.npmjs.org/bigbluebutton-html-plugin-sdk/-/bigbluebutton-html-plugin-sdk-0.0.58.tgz", - "integrity": "sha512-x4Dnt2TiWlosM8vOqq/FCsuG8XCZ//Ab79b/5w7S8nRgeXWmIc942R4tbWZ7CwBGAdGnZvp3mAAqkvB7SYfk0g==", + "version": "0.0.59", + "resolved": "https://registry.npmjs.org/bigbluebutton-html-plugin-sdk/-/bigbluebutton-html-plugin-sdk-0.0.59.tgz", + "integrity": "sha512-HYmV9vkbC8M3CcKizCJMzgYaEA9w3fbRbuGtqDhHFQ0hFrsGP/Cd86gT+toFXKNoG1KatYwhZdMXk4eXNMjywg==", "license": "LGPL-3.0", "dependencies": { "@apollo/client": "^3.8.7", diff --git a/bigbluebutton-html5/package.json b/bigbluebutton-html5/package.json index 8825f0d816..da629b612a 100644 --- a/bigbluebutton-html5/package.json +++ b/bigbluebutton-html5/package.json @@ -56,7 +56,7 @@ "autoprefixer": "^10.4.4", "axios": "^1.7.4", "babel-runtime": "~6.26.0", - "bigbluebutton-html-plugin-sdk": "0.0.58", + "bigbluebutton-html-plugin-sdk": "0.0.59", "bowser": "^2.11.0", "browser-bunyan": "^1.8.0", "classnames": "^2.2.6", From 74dbf029bf4085c3c33b952426692ca20eff84f2 Mon Sep 17 00:00:00 2001 From: Guilherme Leme Date: Wed, 2 Oct 2024 19:09:07 -0300 Subject: [PATCH 5/5] [lms-plugin-adaptation] - Code review --- .../imports/ui/components/common/menu/component.jsx | 3 ++- .../user-list-participants/user-actions/component.tsx | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx b/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx index 32e59839e0..ab0f6b09b8 100644 --- a/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx @@ -172,8 +172,9 @@ class BBBMenu extends React.Component { {label} {a.iconRight ? : null} {(isTitle && titleActions?.length > 0) ? ( - titleActions.map((item) => ( + titleActions.map((item, index) => ( = ({ }); } }; - const t = userDropdownItems.filter( + const titleActions = userDropdownItems.filter( (item: PluginSdk.UserListDropdownInterface) => ( item?.type === UserListDropdownItemType.TITLE_ACTION), ); @@ -333,7 +333,7 @@ const UserActions: React.FC = ({ allowed: true, key: 'userName', label: user.name, - titleActions: t, + titleActions, isTitle: true, }, ...makeDropdownPluginItem(userDropdownItems.filter(