Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: wrong index used to retrieve last data in the data channel #15

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## What is it?

The Pick Random User Plugin shows a modal for moderator to pick a user (mainly viewer but it could also be a moderator) randomly out of the whole list of users present in a meetings.
The Pick Random User Plugin shows a modal for moderator to pick a user (mainly viewer but it could also be a moderator) randomly out of the whole list of users present in a meetings.

![Gif of plugin demo](./public/assets/plugin.gif)

Expand All @@ -24,11 +24,11 @@ npm start
url: http://127.0.0.1:4701/static/PickRandomUserPlugin.js
dataChannels:
- name: pickRandomUser
writePermission: ['presenter']
deletePermission: ['moderator', 'sender']
pushPermission: ['presenter']
replaceOrDeletePermission: ['moderator', 'creator']
- name: modalInformationFromPresenter
writePermission: ['presenter']
deletePermission: ['moderator', 'sender']
pushPermission: ['presenter']
replaceOrDeletePermission: ['moderator', 'creator']
```

## Building the Plugin
Expand All @@ -54,11 +54,11 @@ public:
url: <<PLUGIN_URL>>
dataChannels:
- name: pickRandomUser
writePermission: ['presenter']
deletePermission: ['moderator', 'sender']
pushPermission: ['presenter']
replaceOrDeletePermission: ['moderator', 'creator']
- name: modalInformationFromPresenter
writePermission: ['presenter']
deletePermission: ['moderator', 'sender']
pushPermission: ['presenter']
replaceOrDeletePermission: ['moderator', 'creator']
... // All other configurations
```

Expand Down
15 changes: 8 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"@types/react": "^18.2.13",
"@types/react-dom": "^18.2.6",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"bigbluebutton-html-plugin-sdk": "0.0.48",
"bigbluebutton-html-plugin-sdk": "^0.0.58",
"path": "^0.12.7",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
18 changes: 5 additions & 13 deletions src/components/modal/component.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useEffect, useState } from 'react';
import * as React from 'react';
import * as ReactModal from 'react-modal';
import { PickUserModalProps } from './types';
Expand All @@ -19,8 +18,9 @@ export function PickUserModal(props: PickUserModalProps) {
userFilterViewer,
setUserFilterViewer,
dataChannelPickedUsers,
deletionFunction,
dispatcherPickedUser,
resetPickedUserHistory,
handleBackToPresenterView,
showPresenterView,
} = props;

let userRole: string;
Expand All @@ -36,12 +36,6 @@ export function PickUserModal(props: PickUserModalProps) {
title = 'You have been randomly picked';
}

const [showPresenterView, setShowPresenterView] = useState<boolean>(
currentUser?.presenter && !pickedUser,
);
useEffect(() => {
setShowPresenterView(currentUser?.presenter && !pickedUser);
}, [currentUser, pickedUser]);
return (
<ReactModal
className="plugin-modal"
Expand Down Expand Up @@ -75,13 +69,12 @@ export function PickUserModal(props: PickUserModalProps) {
setFilterOutPresenter,
userFilterViewer,
setUserFilterViewer,
deletionFunction,
resetPickedUserHistory,
handlePickRandomUser,
dataChannelPickedUsers,
pickedUser,
users,
userRole,
dispatcherPickedUser,
}}
/>
) : (
Expand All @@ -90,8 +83,7 @@ export function PickUserModal(props: PickUserModalProps) {
pickedUser,
title,
currentUser,
setShowPresenterView,
dispatcherPickedUser,
handleBackToPresenterView,
}}
/>
)
Expand Down
9 changes: 1 addition & 8 deletions src/components/modal/picked-user-view/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,9 @@ export function PickedUserViewComponent(props: PickedUserViewComponentProps) {
title,
pickedUser,
currentUser,
setShowPresenterView,
dispatcherPickedUser,
handleBackToPresenterView,
} = props;

const handleBackToPresenterView = () => {
if (currentUser?.presenter) {
setShowPresenterView(true);
dispatcherPickedUser(null);
}
};
return (
<div
style={{
Expand Down
4 changes: 1 addition & 3 deletions src/components/modal/picked-user-view/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { CurrentUserData } from 'bigbluebutton-html-plugin-sdk';
import { PushEntryFunction } from 'bigbluebutton-html-plugin-sdk/dist/cjs/data-channel/types';
import { PickedUser } from '../../pick-random-user/types';

export interface PickedUserViewComponentProps {
title: string;
pickedUser: PickedUser;
currentUser: CurrentUserData;
setShowPresenterView: React.Dispatch<React.SetStateAction<boolean>>;
dispatcherPickedUser: PushEntryFunction
handleBackToPresenterView: () => void
}
5 changes: 2 additions & 3 deletions src/components/modal/presenter-view/component.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import { RESET_DATA_CHANNEL } from 'bigbluebutton-html-plugin-sdk';
import { DataChannelEntryResponseType } from 'bigbluebutton-html-plugin-sdk/dist/cjs/data-channel/types';

import { PickedUser } from '../../pick-random-user/types';
Expand Down Expand Up @@ -40,7 +39,7 @@ export function PresenterViewComponent(props: PresenterViewComponentProps) {
setFilterOutPresenter,
userFilterViewer,
setUserFilterViewer,
deletionFunction,
resetPickedUserHistory,
handlePickRandomUser,
dataChannelPickedUsers,
pickedUser,
Expand Down Expand Up @@ -103,7 +102,7 @@ export function PresenterViewComponent(props: PresenterViewComponentProps) {
type="button"
className="clickable"
onClick={() => {
deletionFunction([RESET_DATA_CHANNEL]);
resetPickedUserHistory();
}}
>
Clear All
Expand Down
3 changes: 1 addition & 2 deletions src/components/modal/presenter-view/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { DataChannelEntryResponseType } from 'bigbluebutton-html-plugin-sdk/dist/cjs/data-channel/types';
import { DeleteEntryFunction } from 'bigbluebutton-html-plugin-sdk';
import { PickedUser } from '../../pick-random-user/types';

export interface PresenterViewComponentProps {
filterOutPresenter: boolean;
setFilterOutPresenter: (filter: boolean) => void;
userFilterViewer: boolean;
setUserFilterViewer: (filter: boolean) => void;
deletionFunction: DeleteEntryFunction;
resetPickedUserHistory: () => void;
handlePickRandomUser: () => void;
dataChannelPickedUsers?: DataChannelEntryResponseType<PickedUser>[];
pickedUser: PickedUser;
Expand Down
9 changes: 5 additions & 4 deletions src/components/modal/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CurrentUserData, DeleteEntryFunction } from 'bigbluebutton-html-plugin-sdk';
import { DataChannelEntryResponseType, PushEntryFunction } from 'bigbluebutton-html-plugin-sdk/dist/cjs/data-channel/types';
import { CurrentUserData } from 'bigbluebutton-html-plugin-sdk';
import { DataChannelEntryResponseType } from 'bigbluebutton-html-plugin-sdk/dist/cjs/data-channel/types';
import { PickedUser } from '../pick-random-user/types';

export interface PickUserModalProps {
Expand All @@ -14,6 +14,7 @@ export interface PickUserModalProps {
userFilterViewer: boolean;
setUserFilterViewer: (filter: boolean) => void;
dataChannelPickedUsers?: DataChannelEntryResponseType<PickedUser>[];
deletionFunction: DeleteEntryFunction;
dispatcherPickedUser: PushEntryFunction;
resetPickedUserHistory: () => void;
showPresenterView: boolean;
handleBackToPresenterView: () => void;
}
60 changes: 48 additions & 12 deletions src/components/pick-random-user/component.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import * as React from 'react';
import { useState, useEffect } from 'react';

import { BbbPluginSdk, PluginApi } from 'bigbluebutton-html-plugin-sdk';
import {
BbbPluginSdk,
DataChannelTypes,
PluginApi,
RESET_DATA_CHANNEL,
} from 'bigbluebutton-html-plugin-sdk';
import {
ModalInformationFromPresenter,
PickRandomUserPluginProps,
PickedUser,
PickedUserIsShowing,
UsersMoreInformationGraphqlResponse,
} from './types';
import { USERS_MORE_INFORMATION } from './queries';
Expand All @@ -22,12 +28,16 @@ function PickRandomUserPlugin({ pluginUuid: uuid }: PickRandomUserPluginProps) {
const pluginApi: PluginApi = BbbPluginSdk.getPluginApi(uuid);
const currentUserInfo = pluginApi.useCurrentUser();
const { data: currentUser } = currentUserInfo;
const [showPresenterView, setShowPresenterView] = useState<boolean>(
currentUser?.presenter && !pickedUser,
);
const allUsersInfo = pluginApi
.useCustomSubscription<UsersMoreInformationGraphqlResponse>(USERS_MORE_INFORMATION);
const { data: allUsers } = allUsersInfo;

const [pickedUserFromDataChannelResponse, dispatcherPickedUser, deletionFunction] = pluginApi.useDataChannel<PickedUser>('pickRandomUser');
const [modalInformationFromPresenter, dispatchModalInformationFromPresenter] = pluginApi.useDataChannel<ModalInformationFromPresenter>('modalInformationFromPresenter');
const { data: pickedUserFromDataChannelResponse, pushEntry: pushEntryPickedUser, deleteEntry: deleteEntryPickedUser } = pluginApi.useDataChannel<PickedUser>('pickRandomUser');
const { data: pickedUserIsShowingResponse, pushEntry: pushEntryPickedUserIsShowing } = pluginApi.useDataChannel<PickedUserIsShowing>('pickRandomUser', DataChannelTypes.LATEST_ITEM, 'isShowing');
const { data: modalInformationFromPresenter, pushEntry: pushEntryModalInformationFromPresenter } = pluginApi.useDataChannel<ModalInformationFromPresenter>('modalInformationFromPresenter');

const pickedUserFromDataChannel = {
data: pickedUserFromDataChannelResponse?.data,
Expand All @@ -49,6 +59,7 @@ function PickRandomUserPlugin({ pluginUuid: uuid }: PickRandomUserPluginProps) {
user: allUsers?.user.filter((user) => {
let roleFilter = true;
if (userFilterViewer) roleFilter = user.role === Role.VIEWER;
// Check if data has loaded
if (pickedUserFromDataChannel.data) {
return roleFilter && pickedUserFromDataChannel
.data.findIndex(
Expand All @@ -66,31 +77,46 @@ function PickRandomUserPlugin({ pluginUuid: uuid }: PickRandomUserPluginProps) {
if (usersToBePicked && usersToBePicked.user.length > 0 && currentUser?.presenter) {
const randomIndex = Math.floor(Math.random() * usersToBePicked.user.length);
const randomlyPickedUser = usersToBePicked.user[randomIndex];
dispatcherPickedUser(randomlyPickedUser);
pushEntryPickedUser(randomlyPickedUser);
pushEntryPickedUserIsShowing({ isShowing: true });
}
setShowModal(true);
};

const resetPickedUserHistory = () => {
deleteEntryPickedUser([RESET_DATA_CHANNEL]);
};

const handleBackToPresenterView = () => {
if (currentUser?.presenter) {
setShowPresenterView(true);
pushEntryPickedUserIsShowing({ isShowing: false });
}
};

const handleCloseModal = (): void => {
if (currentUser?.presenter) {
dispatchModalInformationFromPresenter({
pushEntryModalInformationFromPresenter({
skipModerators: userFilterViewer,
skipPresenter: filterOutPresenter,
});
dispatcherPickedUser(null);
pushEntryPickedUserIsShowing({ isShowing: false });
}
setShowModal(false);
};

// Check the picked-user response in data-channel
useEffect(() => {
// If data already loaded and there is some picked-user:
// then set local state picked-user and open modal
if (pickedUserFromDataChannel.data
&& pickedUserFromDataChannel.data?.length > 0) {
const pickedUserToUpdate = pickedUserFromDataChannel
.data[
pickedUserFromDataChannel.data.length - 1
];
.data[0];
setPickedUser(pickedUserToUpdate?.payloadJson);
if (pickedUserToUpdate?.payloadJson) setShowModal(true);
// If data already loaded, but there is none picked user
// Then set local picked-user to null
} else if (pickedUserFromDataChannel.data
&& pickedUserFromDataChannel.data?.length === 0) {
setPickedUser(null);
Expand All @@ -103,8 +129,16 @@ function PickRandomUserPlugin({ pluginUuid: uuid }: PickRandomUserPluginProps) {
}, [pickedUser]);

useEffect(() => {
if (!currentUser?.presenter && dispatchModalInformationFromPresenter) handleCloseModal();
if (!currentUser?.presenter && pushEntryModalInformationFromPresenter) handleCloseModal();
}, [currentUser]);

const showPickedUser: boolean = (pickedUserIsShowingResponse?.data)
? pickedUserIsShowingResponse?.data[0]?.payloadJson.isShowing : false;

// Keeps track if the current user looses presenter status and if it needs to show the picked-user
useEffect(() => {
setShowPresenterView(currentUser?.presenter && !showPickedUser);
}, [currentUser, pickedUserIsShowingResponse]);
return (
<>
<PickUserModal
Expand All @@ -120,8 +154,10 @@ function PickRandomUserPlugin({ pluginUuid: uuid }: PickRandomUserPluginProps) {
userFilterViewer,
setUserFilterViewer,
dataChannelPickedUsers: pickedUserFromDataChannel.data,
dispatcherPickedUser,
deletionFunction,
resetPickedUserHistory,
showPickedUser,
handleBackToPresenterView,
showPresenterView,
}}
/>
<ActionButtonDropdownManager
Expand Down
4 changes: 4 additions & 0 deletions src/components/pick-random-user/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ export interface PickedUser {
color: string;
}

export interface PickedUserIsShowing {
isShowing: boolean;
}

export interface PickRandomUserPluginProps {
pluginName: string,
pluginUuid: string,
Expand Down