Skip to content

Commit

Permalink
fix: open presentation if minimized
Browse files Browse the repository at this point in the history
Open the presentation if its minimized during whiteboard step.
Minimize again in the end.

Fix eslint errors.
  • Loading branch information
germanocaumo committed Jul 4, 2024
1 parent a53e961 commit 0137589
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 39 deletions.
105 changes: 73 additions & 32 deletions src/tour/component.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
/* eslint-disable global-require */
/* eslint-disable import/no-dynamic-require */
import * as React from 'react';
import { useEffect } from 'react';
import Shepherd from "shepherd.js";
import {IntlShape, createIntl, defineMessages} from 'react-intl'
import Shepherd from 'shepherd.js';
import { IntlShape, createIntl, defineMessages } from 'react-intl';
import {
BbbPluginSdk, OptionsDropdownOption, PluginApi,
pluginLogger, UserListUiDataNames, IntlLocaleUiDataNames,
LayoutPresentatioAreaUiDataNames, UiLayouts,
} from 'bigbluebutton-html-plugin-sdk';
import { TourPluginProps } from './types';
import getTourFeatures from "./getTourFeatures";
import "shepherd.js/dist/css/shepherd.css";
import "./custom.css";
import getTourFeatures from './getTourFeatures';
import 'shepherd.js/dist/css/shepherd.css';
import './custom.css';

const intlMessages = defineMessages({
start: {
Expand All @@ -23,8 +26,14 @@ const intlMessages = defineMessages({
* @param {IntlShape} intl Intl object from react-intl
* @param {Object} URLS object with urls to link in know more buttons (from settings)
*/
export function startTour(intl: IntlShape, URLS: Object, pluginApi: PluginApi, userListOpened: Boolean) {
// Docs: https://docs.shepherdpro.com/guides/usage/
export function startTour(
intl: IntlShape,
URLS: object,
pluginApi: PluginApi,
userListOpened: boolean,
presentationInitiallyOpened: boolean,
) {
// Docs: https://docs.shepherdpro.com/guides/usage/
const tour = new Shepherd.Tour({
defaultStepOptions: {
cancelIcon: {
Expand All @@ -35,41 +44,58 @@ export function startTour(intl: IntlShape, URLS: Object, pluginApi: PluginApi, u
useModalOverlay: true,
});

for (const feature of getTourFeatures(intl, tour, URLS, pluginApi, userListOpened)) {
for (const step of feature.steps) {
getTourFeatures(
intl,
tour,
URLS,
pluginApi,
userListOpened,
presentationInitiallyOpened,
).forEach((feature) => {
feature.steps.forEach((step) => {
/* @ts-ignore */
tour.addStep({
...step,
// Only show step if the element is visible
showOn: () => {
return !!document.querySelector(
step.attachTo.element
);
},
showOn: () => !!document.querySelector(
step.attachTo.element,
),
});
}
}
});
});

tour.start();
}

function TourPlugin(
{ pluginUuid: uuid }: TourPluginProps,
): React.ReactElement<TourPluginProps> {
BbbPluginSdk.initialize(uuid);
const [userListInitiallyOpened, setUserListInitiallyOpened] = React.useState(true);
const pluginApi: PluginApi = BbbPluginSdk.getPluginApi(uuid);
const userListOpened = pluginApi.useUiData(UserListUiDataNames.USER_LIST_IS_OPEN, { value: true });
const [userListInitiallyOpened, setUserListInitiallyOpened] = React.useState(true);
const [presentationInitiallyOpened, setPresentationInitiallyOpened] = React.useState(true);

const userListOpened = pluginApi.useUiData(UserListUiDataNames.USER_LIST_IS_OPEN, {
value: true,
});

const currentLocale = pluginApi.useUiData(IntlLocaleUiDataNames.CURRENT_LOCALE, {
locale: 'en',
fallbackLocale: 'en',
});

const layoutInformation = pluginApi.useUiData(LayoutPresentatioAreaUiDataNames.CURRENT_ELEMENT, [{
isOpen: presentationInitiallyOpened,
currentElement: UiLayouts.WHITEBOARD,
}]);

const settings = pluginApi.usePluginSettings()?.data;

let messages = {};
try {
messages = require(`../locales/${currentLocale.locale.replace('-', '_')}.json`)
messages = require(`../locales/${currentLocale.locale.replace('-', '_')}.json`);
} catch {
messages = require(`../locales/${currentLocale.fallbackLocale.replace('-', '_')}.json`)
messages = require(`../locales/${currentLocale.fallbackLocale.replace('-', '_')}.json`);
}

const intl = createIntl({
Expand All @@ -81,23 +107,31 @@ function TourPlugin(
useEffect(() => {
const endTourEvents = ['cancel', 'complete'];

//restores the panel state after finishing the tour
endTourEvents.forEach(event => Shepherd.on(event, () => {
// restores the panel state after finishing the tour
endTourEvents.forEach((event) => Shepherd.on(event, () => {
if (userListInitiallyOpened !== userListOpened.value) {
if (userListInitiallyOpened) {
pluginApi.uiCommands.sidekickOptionsContainer.open();
} else {
pluginApi.uiCommands.sidekickOptionsContainer.close();
}
};
//removes events
endTourEvents.forEach(event => Shepherd.off(event, undefined));
}
// restores presentation state after finishing the tour
if (presentationInitiallyOpened !== layoutInformation[0]?.isOpen) {
if (presentationInitiallyOpened) {
pluginApi.uiCommands.presentationArea.open();

Check failure on line 122 in src/tour/component.tsx

View workflow job for this annotation

GitHub Actions / ts-code-compilation

Property 'presentationArea' does not exist on type 'UiCommands'.
} else {
pluginApi.uiCommands.presentationArea.close();

Check failure on line 124 in src/tour/component.tsx

View workflow job for this annotation

GitHub Actions / ts-code-compilation

Property 'presentationArea' does not exist on type 'UiCommands'.
}
}
// removes events
endTourEvents.forEach((event) => Shepherd.off(event, undefined));
}));
return () => {
//removes events
endTourEvents.forEach(event => Shepherd.off(event, undefined));
}
}, [userListOpened]);
// removes events
endTourEvents.forEach((event) => Shepherd.off(event, undefined));
};
}, [userListOpened, layoutInformation]);

useEffect(() => {
pluginApi.setOptionsDropdownItems([
Expand All @@ -106,17 +140,24 @@ function TourPlugin(
icon: 'presentation',
onClick: async () => {
setUserListInitiallyOpened(userListOpened.value);
setPresentationInitiallyOpened(layoutInformation[0]?.isOpen);
pluginLogger.info('Starting Tour');
// ensure only userList is open (to also work on Mobile)
pluginApi.uiCommands.sidekickOptionsContainer.close();
pluginApi.uiCommands.sidekickOptionsContainer.open();
// wait some time for the ui to update
await new Promise(resolve => setTimeout(resolve, 1000));
startTour(intl, settings?.url, pluginApi, userListOpened.value);
await new Promise((resolve) => { setTimeout(resolve, 1000); });
startTour(
intl,
settings?.url,
pluginApi,
userListOpened.value,
layoutInformation[0]?.isOpen,
);
},
}),
]);
}, [userListOpened, currentLocale, settings]);
}, [userListOpened, currentLocale, settings, layoutInformation]);

return null;
}
Expand Down
27 changes: 20 additions & 7 deletions src/tour/getTourFeatures.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
* @property {string} name Identifies the feature
* @property {Date} date Refers to when the feature was "released".
* This is used to only present features newer than the last time the user saw the tour.
* @property {Object[]} steps An array of objects where each object is the options to a Step (Shepherd.js)
* @property {Object[]} steps An array of objects where
* each object is the options to a Step (Shepherd.js)
* Docs: https://shepherdjs.dev/docs/Step.html#Step
*/

Expand Down Expand Up @@ -149,7 +150,14 @@ const getCloseTourButton = (intl, tour) => ({
action: tour.complete,
});

const getTourFeatures = (intl, tour, URLS, pluginApi, userListOpened) => {
const getTourFeatures = (
intl,
tour,
URLS,
pluginApi,
userListOpened,
presentationInitiallyOpened,
) => {
const actions = {
closePanel: () => {
pluginApi.uiCommands.sidekickOptionsContainer.close();
Expand All @@ -159,6 +167,11 @@ const getTourFeatures = (intl, tour, URLS, pluginApi, userListOpened) => {
pluginApi.uiCommands.sidekickOptionsContainer.open();
}
},
openPresentation: () => {
if (!presentationInitiallyOpened) {
pluginApi.uiCommands.presentationArea.open();
}
},
};

const microphoneToggleFeature = {
Expand Down Expand Up @@ -315,7 +328,7 @@ const getTourFeatures = (intl, tour, URLS, pluginApi, userListOpened) => {
getNextButton(intl, tour),
],
when: {
'before-show': () => actions.closePanel(),
'before-show': () => actions.openPresentation(),
},
},
{
Expand All @@ -328,7 +341,7 @@ const getTourFeatures = (intl, tour, URLS, pluginApi, userListOpened) => {
getNextButton(intl, tour),
],
when: {
'before-show': () => actions.closePanel(),
'before-show': () => actions.openPresentation(),
},
},
{
Expand All @@ -342,7 +355,7 @@ const getTourFeatures = (intl, tour, URLS, pluginApi, userListOpened) => {
getNextButton(intl, tour),
],
when: {
'before-show': () => actions.closePanel(),
'before-show': () => actions.openPresentation(),
},
},
{
Expand All @@ -355,7 +368,7 @@ const getTourFeatures = (intl, tour, URLS, pluginApi, userListOpened) => {
getNextButton(intl, tour),
],
when: {
'before-show': () => actions.closePanel(),
'before-show': () => actions.openPresentation(),
},
},
],
Expand Down Expand Up @@ -527,8 +540,8 @@ const getTourFeatures = (intl, tour, URLS, pluginApi, userListOpened) => {
videoFeature,
screnshareFeature,
interactionsFeature,
closePresentationFeature,
whiteboardFeature,
closePresentationFeature,
userListToggleFeature,
recordingFeature,
connectionStatusFeature,
Expand Down

0 comments on commit 0137589

Please sign in to comment.