Skip to content
Open
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
8 changes: 4 additions & 4 deletions src/components/bars/top/buttons/swap.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ const intlMessages = defineMessages({
},
});

const propTypes = { toggleSwap: PropTypes.func };
const propTypes = { toggleSwap: PropTypes.func, hidePresentation: PropTypes.bool };

const defaultProps = { toggleSwap: () => {} };
const defaultProps = { toggleSwap: () => { }, hidePresentation: false };

const Swap = ({ toggleSwap }) => {
const Swap = ({ toggleSwap, hidePresentation }) => {
const intl = useIntl();

if (!layout.control || !config.swap || layout.single) return null;
if (!layout.control || !config.swap || layout.single || hidePresentation) return null;

return (
<Button
Expand Down
11 changes: 7 additions & 4 deletions src/components/bars/top/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,22 @@ const propTypes = {
section: PropTypes.bool,
toggleSection: PropTypes.func,
toggleSwap: PropTypes.func,
hidePresentation: PropTypes.bool,
};

const defaultProps = {
openModal: () => {},
openModal: () => { },
section: false,
toggleSection: () => {},
toggleSwap: () => {},
toggleSection: () => { },
toggleSwap: () => { },
};

const Top = ({
openModal,
section,
toggleSection,
toggleSwap,
hidePresentation,
}) => {

return (
Expand All @@ -43,7 +45,7 @@ const Top = ({
<div className="right">
<ThemeButton />
<SearchButton openSearch={() => openModal(ID.SEARCH)} />
<SwapButton toggleSwap={toggleSwap} />
<SwapButton toggleSwap={toggleSwap} hidePresentation={hidePresentation} />
</div>
</div>
);
Expand All @@ -54,6 +56,7 @@ Top.defaultProps = defaultProps;

// Checks the side section state
const areEqual = (prevProps, nextProps) => {
if (prevProps.hidePresentation !== nextProps.hidePresentation) return false;
return prevProps.section === nextProps.section;
};

Expand Down
11 changes: 7 additions & 4 deletions src/components/player/content/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Presentation from 'components/presentation';
import TldrawPresentation from 'components/tldraw';
import TldrawPresentationV2 from 'components/tldraw_v2';
import { getTldrawBbbVersion, isTldrawWhiteboard as isTldraw } from 'utils/tldraw';
import { useCurrentInterval, useShouldShowScreenShare } from 'components/utils/hooks';
import { useCurrentInterval, useLayoutSwap } from 'components/utils/hooks';
import Screenshare from 'components/screenshare';
import Thumbnails from 'components/thumbnails';
import FullscreenButton from 'components/player/buttons/fullscreen';
Expand All @@ -21,14 +21,15 @@ const Content = ({
search,
swap,
toggleFullscreen,
hidePresentation,
}) => {
const {
index,
} = useCurrentInterval(storage.tldraw);

const shouldShowScreenshare = useShouldShowScreenShare();
const { showScreenshare } = useLayoutSwap();

if (layout.single) return null;
if (layout.single || hidePresentation) return null;

const isTldrawWhiteboard = isTldraw();

Expand Down Expand Up @@ -60,7 +61,7 @@ const Content = ({
{presentation}
{layout.screenshare ? (
// video-js doesn't mount properly when not mounted in time
<span style={!shouldShowScreenshare ? {
<span style={!showScreenshare ? {
display: 'none',
width: '100%',
height: '100%'
Expand Down Expand Up @@ -88,6 +89,8 @@ const areEqual = (prevProps, nextProps) => {

if (prevProps.swap !== nextProps.swap) return false;

if (prevProps.hidePresentation !== nextProps.hidePresentation) return false;

if (!isEqual(prevProps.search, nextProps.search)) return false;

return true;
Expand Down
17 changes: 16 additions & 1 deletion src/components/player/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
import { ID } from 'utils/constants';
import layout from 'utils/layout';
import Shortcuts from 'utils/shortcuts';
import { useLayoutSwap } from 'components/utils/hooks';
import './index.scss';

const intlMessages = defineMessages({
Expand All @@ -39,6 +40,17 @@ const Player = () => {

const shortcuts = useRef();

const { showPresentation } = useLayoutSwap();
const hidePresentation = showPresentation === false;

useEffect(() => {
if (showPresentation === false) {
setSwap(true);
} else {
setSwap(false);
}
}, [showPresentation]);

useEffect(() => {
const { seconds } = config.seek;

Expand Down Expand Up @@ -67,7 +79,7 @@ const Player = () => {
const style = {
'fullscreen-content': fullscreen,
'hidden-section': !section,
'single-content': layout.single,
'single-content': layout.single || hidePresentation,
};

return (
Expand All @@ -81,11 +93,13 @@ const Player = () => {
section={section}
toggleSection={() => setSection(prevSection => !prevSection)}
toggleSwap={() => setSwap(prevSwap => !prevSwap)}
hidePresentation={hidePresentation}
/>
<Media
fullscreen={fullscreen}
swap={swap}
toggleFullscreen={() => setFullscreen(prevFullscreen => !prevFullscreen)}
hidePresentation={hidePresentation}
/>
<Application />
<Content
Expand All @@ -94,6 +108,7 @@ const Player = () => {
search={search}
swap={swap}
toggleFullscreen={() => setFullscreen(prevFullscreen => !prevFullscreen)}
hidePresentation={hidePresentation}
/>
<BottomBar />
<Modal
Expand Down
5 changes: 4 additions & 1 deletion src/components/player/media/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ const Media = ({
fullscreen,
swap,
toggleFullscreen,
hidePresentation,
}) => {

return (
<div className={cx('media', { 'swapped-media': swap || layout.single })}>
<div className={cx('media', { 'swapped-media': swap || layout.single || hidePresentation })}>
<FullscreenButton
content={LAYOUT.MEDIA}
fullscreen={fullscreen}
Expand All @@ -28,6 +29,8 @@ const Media = ({
const areEqual = (prevProps, nextProps) => {
if (prevProps.fullscreen !== nextProps.fullscreen) return false;

if (prevProps.hidePresentation !== nextProps.hidePresentation) return false;

if (prevProps.swap !== nextProps.swap) return false;

return true;
Expand Down
6 changes: 3 additions & 3 deletions src/components/presentation/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Canvas from './canvas';
import {
useCurrentContent,
useCurrentIndex,
useShouldShowScreenShare,
useLayoutSwap,
} from 'components/utils/hooks';
import { ID } from 'utils/constants';
import storage from 'utils/data/storage';
Expand Down Expand Up @@ -61,11 +61,11 @@ const Presentation = () => {
const viewBox = getViewBox(currentPanzoomIndex);

const started = currentPanzoomIndex !== -1;
const shouldShowScreenshare = useShouldShowScreenShare();
const { showScreenshare } = useLayoutSwap();
return (
<div
aria-label={intl.formatMessage(intlMessages.aria)}
className={cx('presentation-wrapper', { inactive: (currentContent !== ID.PRESENTATION && shouldShowScreenshare) })}
className={cx('presentation-wrapper', { inactive: (currentContent !== ID.PRESENTATION && showScreenshare) })}
id={ID.PRESENTATION}
>
<div className={cx('presentation', { logo: !started })}>
Expand Down
84 changes: 54 additions & 30 deletions src/components/thumbnails/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,51 +78,75 @@ const Thumbnails = ({

const items = useMemo(() => {
const thumbnails = storage.thumbnails;
const layoutSwap = storage.layoutSwap ?? [];
const layoutSwap = (storage.layoutSwap ?? []).filter(item => item.hasOwnProperty('showScreenshare'));
const merged = [...thumbnails, ...layoutSwap];
const sorted = merged.sort((a, b) => a.timestamp - b.timestamp);

const addThumbsForSwap = sorted.map((item, index, arr) => {
// If the item is a standard thumbnail (not a layout event), preserve it.
if (!item.hasOwnProperty('showScreenshare')) {
return item;
}

const previousItem = arr[index - 1];
const nextItem = arr[index + 1];
if (item.hasOwnProperty('showScreenshare')) {
if (!item.showScreenshare) {
const previousThumbs = arr.slice(0, index)
const Thumbnail = previousThumbs.find((t) => t.src && t.src !== 'screenshare');
// don't add if the src is the same as before
if (Thumbnail?.src === previousItem?.src) {
return null;
} else {
return {
...item,
src: Thumbnail?.src ?? '',
alt: Thumbnail?.alt ?? '',
};
}
} else if (
item.showScreenshare
&& (nextItem && nextItem.src !== 'screenshare')
&& (previousItem && previousItem.src !== 'screenshare')

// Handle logic when screenshare is inactive (restore presentation)
if (!item.showScreenshare) {
// Prevent duplicate consecutive 'restore' actions
if (
previousItem?.hasOwnProperty('showScreenshare')
&& !previousItem.showScreenshare
) {
return null;
}

const previousThumbs = arr.slice(0, index);
const restoredSlide = previousThumbs.find((t) => t.src && t.src !== 'screenshare');

// Only add if the restored slide is different from the immediate previous item
if (restoredSlide?.src && restoredSlide?.src !== previousItem?.src) {
return {
...item,
src: 'screenshare',
alt: 'screenshare',
}
src: restoredSlide.src,
alt: restoredSlide.alt ?? '',
};
}
return null;
}
return item;
}).filter((item) => item !== null);

const reworkIds = addThumbsForSwap.map((item, index) => {
return {
...item,
id: index + 1,
// Handle logic when screenshare is active
if (item.showScreenshare) {
// Prevent duplicate consecutive 'screenshare' actions
if (
previousItem?.hasOwnProperty('showScreenshare')
&& previousItem.showScreenshare
) {
return null;
}

// Ensure strictly valid boundaries (must have valid next/prev items)
const hasValidNeighbors =
(nextItem && nextItem.src !== 'screenshare') &&
(previousItem && previousItem.src !== 'screenshare');

if (hasValidNeighbors) {
return {
...item,
src: 'screenshare',
alt: 'screenshare',
};
}
}
});

return reworkIds;
return null;
}).filter((item) => item !== null);

// Re-index all items sequentially
return addThumbsForSwap.map((item, index) => ({
...item,
id: index + 1,
}));
}, []);

const currentIndex = useCurrentIndex(items);
Expand Down
6 changes: 3 additions & 3 deletions src/components/tldraw/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
useCurrentContent,
useCurrentIndex,
useCurrentInterval,
useShouldShowScreenShare,
useLayoutSwap,
} from 'components/utils/hooks';
import { ID } from 'utils/constants';
import storage from 'utils/data/storage';
Expand Down Expand Up @@ -119,7 +119,7 @@ const TldrawPresentation = ({ size }) => {
const currentPanzoomIndex = useCurrentIndex(storage.panzooms);
const currentSlideIndex = useCurrentIndex(storage.slides);
const started = currentPanzoomIndex !== -1;
const shouldShowScreenShare = useShouldShowScreenShare();
const { showScreenshare } = useLayoutSwap();
const result = SlideData(tldrawAPI);

let { assets, shapes, scaleRatio } = result;
Expand Down Expand Up @@ -158,7 +158,7 @@ const TldrawPresentation = ({ size }) => {
return (
<div
aria-label={intl.formatMessage(intlMessages.aria)}
className={cx('presentation-wrapper', { inactive: (currentContent !== ID.PRESENTATION && shouldShowScreenShare) })}
className={cx('presentation-wrapper', { inactive: (currentContent !== ID.PRESENTATION && showScreenshare) })}
id={ID.PRESENTATION}
>
{!started
Expand Down
6 changes: 3 additions & 3 deletions src/components/tldraw_v2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
useCurrentContent,
useCurrentIndex,
useCurrentInterval,
useShouldShowScreenShare,
useLayoutSwap,
} from 'components/utils/hooks';
import { ID } from 'utils/constants';
import storage from 'utils/data/storage';
Expand Down Expand Up @@ -103,7 +103,7 @@ const TldrawPresentationV2 = ({ size }) => {
const started = currentPanzoomIndex !== -1;

const result = SlideData(tldrawAPI);
const shouldShowScreenshare = useShouldShowScreenShare();
const { showScreenshare } = useLayoutSwap();

let { assets, shapes, scaleRatio } = result;
const {
Expand Down Expand Up @@ -160,7 +160,7 @@ const TldrawPresentationV2 = ({ size }) => {
return (
<div
aria-label={intl.formatMessage(intlMessages.aria)}
className={cx('presentation-wrapper', { inactive: (currentContent !== ID.PRESENTATION && shouldShowScreenshare) })}
className={cx('presentation-wrapper', { inactive: (currentContent !== ID.PRESENTATION && showScreenshare) })}
id={ID.PRESENTATION}
>{!started
? <div className={cx('presentation', 'logo')} />
Expand Down
Loading