Skip to content

Commit

Permalink
feat: allow fullscreen mode (graasp#560)
Browse files Browse the repository at this point in the history
  • Loading branch information
juancarlosfarah authored Mar 15, 2024
1 parent ded05b3 commit fd230cc
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 6 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"react": "18.2.0",
"react-accessible-treeview": "2.8.3",
"react-dom": "18.2.0",
"react-fullscreen-crossbrowser": "1.1.3",
"react-ga4": "2.1.0",
"react-i18next": "14.0.5",
"react-intersection-observer": "9.8.1",
Expand Down
4 changes: 3 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ export const App = (): JSX.Element => {
};
const HomePageWithAuthorization = withAuthorization(HomePage, props);

const fullscreen = Boolean(searchParams.get('fullscreen') === 'true');

return (
<Routes>
<Route element={<PageWrapper />}>
<Route element={<PageWrapper fullscreen={fullscreen} />}>
<Route path={buildMainPath()} element={<ItemPage />} />
<Route path={HOME_PATH} element={<HomePageWithAuthorization />} />
<Route path="*" element={<Navigate to={HOME_PATH} />} />
Expand Down
10 changes: 9 additions & 1 deletion src/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@ import { CurrentMemberContextProvider } from '@/contexts/CurrentMemberContext';

import App from './App';

const globalStyles = <GlobalStyles styles={{ p: { fontSize: '1rem' } }} />;
const globalStyles = (
<GlobalStyles
styles={{
p: { fontSize: '1rem' },
// required for fullscreen
'::backdrop': { backgroundColor: 'white' },
}}
/>
);

const Root = (): JSX.Element => (
<QueryClientProvider client={queryClient}>
Expand Down
2 changes: 2 additions & 0 deletions src/config/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export const buildDocumentId = (id: string): string => `document-${id}`;
export const buildAppId = (id: string): string => `app-${id}`;
export const FOLDER_NAME_TITLE_CLASS = `folderNameTitle`;

export const ITEM_FULLSCREEN_BUTTON_ID = 'itemFullscreenButton';

export const ITEM_CHATBOX_ID = 'chatbox';
export const ITEM_CHATBOX_BUTTON_ID = 'itemChatboxButton';

Expand Down
9 changes: 9 additions & 0 deletions src/contexts/LayoutContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ type LayoutContextType = {
setIsPinnedMenuOpen: (state: boolean) => void;
isChatboxMenuOpen: boolean;
setIsChatboxMenuOpen: (state: boolean) => void;
isFullscreen: boolean;
setIsFullscreen: (state: boolean) => void;
};

const LayoutContext = createContext<LayoutContextType>({
isPinnedMenuOpen: true,
setIsPinnedMenuOpen: () => null,
isChatboxMenuOpen: false,
setIsChatboxMenuOpen: () => null,
isFullscreen: false,
setIsFullscreen: () => null,
});

type Props = {
Expand All @@ -25,6 +29,7 @@ export const LayoutContextProvider = ({ children }: Props): JSX.Element => {

const [isPinnedMenuOpen, setIsPinnedMenuOpen] = useState<boolean>(!isMobile);
const [isChatboxMenuOpen, setIsChatboxMenuOpen] = useState<boolean>(false);
const [isFullscreen, setIsFullscreen] = useState<boolean>(false);

useEffect(() => {
setIsPinnedMenuOpen(!isMobile);
Expand All @@ -36,12 +41,16 @@ export const LayoutContextProvider = ({ children }: Props): JSX.Element => {
setIsPinnedMenuOpen,
isChatboxMenuOpen,
setIsChatboxMenuOpen,
isFullscreen,
setIsFullscreen,
}),
[
isPinnedMenuOpen,
setIsPinnedMenuOpen,
isChatboxMenuOpen,
setIsChatboxMenuOpen,
isFullscreen,
setIsFullscreen,
],
);

Expand Down
2 changes: 2 additions & 0 deletions src/langs/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ export const PLAYER = {
GRAASP_PLAYER: 'GRAASP_PLAYER',
SHOW_CHAT_TOOLTIP: 'SHOW_CHAT_TOOLTIP',
HIDE_CHAT_TOOLTIP: 'HIDE_CHAT_TOOLTIP',
ENTER_FULLSCREEN_TOOLTIP: 'ENTER_FULLSCREEN_TOOLTIP',
EXIT_FULLSCREEN_TOOLTIP: 'EXIT_FULLSCREEN_TOOLTIP',
SHOW_PINNED_ITEMS_TOOLTIP: 'SHOW_PINNED_ITEMS_TOOLTIP',
HIDE_PINNED_ITEMS_TOOLTIP: 'HIDE_PINNED_ITEMS_TOOLTIP',
PINNED_ITEMS: 'PINNED_ITEMS',
Expand Down
2 changes: 2 additions & 0 deletions src/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
"GRAASP_PLAYER": "Graasp Player",
"SHOW_CHAT_TOOLTIP": "Show chat",
"HIDE_CHAT_TOOLTIP": "Hide chat",
"EXIT_FULLSCREEN_TOOLTIP": "Exit fullscreen",
"ENTER_FULLSCREEN_TOOLTIP": "Enter fullscreen",
"SHOW_PINNED_ITEMS_TOOLTIP": "Show pinned items",
"HIDE_PINNED_ITEMS_TOOLTIP": "Hide pinned items",
"PINNED_ITEMS": "Pinned items",
Expand Down
7 changes: 6 additions & 1 deletion src/modules/item/NavigationButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ const NavigationButton = ({
};

return (
<AppBar position="fixed" color="secondary" sx={{ top: 'auto', bottom: 0 }}>
// z-index is 998 because cookie banner is 999
<AppBar
position="fixed"
color="secondary"
sx={{ top: 'auto', bottom: 0, zIndex: 998 }}
>
<Toolbar>
{prev ? (
<Button
Expand Down
14 changes: 13 additions & 1 deletion src/modules/layout/PageWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ const LinkComponent = ({
children: JSX.Element;
}): JSX.Element => <StyledLink to={HOME_PATH}>{children}</StyledLink>;

const PageWrapper = (): JSX.Element => {
type PageWrapperProps = {
fullscreen: boolean;
};

const PageWrapper = ({ fullscreen }: PageWrapperProps): JSX.Element => {
const { t } = usePlayerTranslation();
const theme = useTheme();
const { isMobile } = useMobileView();
Expand All @@ -78,6 +82,14 @@ const PageWrapper = (): JSX.Element => {
},
};

if (fullscreen) {
return (
<ItemContextProvider rootId={rootId}>
<Outlet />
</ItemContextProvider>
);
}

return (
<ItemContextProvider rootId={rootId}>
<Main
Expand Down
50 changes: 48 additions & 2 deletions src/modules/rightPanel/SideContent.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import Fullscreen from 'react-fullscreen-crossbrowser';
import { useSearchParams } from 'react-router-dom';

import ForumIcon from '@mui/icons-material/Forum';
import EnterFullscreenIcon from '@mui/icons-material/Fullscreen';
import ExitFullscreenIcon from '@mui/icons-material/FullscreenExit';
import PushPinIcon from '@mui/icons-material/PushPin';
import { Grid, Stack, Tooltip, styled } from '@mui/material';
import IconButton from '@mui/material/IconButton';
Expand All @@ -22,6 +27,7 @@ import { DRAWER_WIDTH, FLOATING_BUTTON_Z_INDEX } from '../../config/constants';
import {
CHATBOX_DRAWER_ID,
ITEM_CHATBOX_BUTTON_ID,
ITEM_FULLSCREEN_BUTTON_ID,
ITEM_PINNED_BUTTON_ID,
ITEM_PINNED_ID,
} from '../../config/selectors';
Expand Down Expand Up @@ -66,12 +72,15 @@ type Props = {
const SideContent = ({ content, item }: Props): JSX.Element | null => {
const { descendants, rootId } = useItemContext();
const { data: tags } = hooks.useItemsTags(descendants?.map(({ id }) => id));
const [searchParams] = useSearchParams();

const {
isPinnedMenuOpen,
setIsPinnedMenuOpen,
isChatboxMenuOpen,
setIsChatboxMenuOpen,
isFullscreen,
setIsFullscreen,
} = useLayoutContext();

const { t } = usePlayerTranslation();
Expand Down Expand Up @@ -114,6 +123,10 @@ const SideContent = ({ content, item }: Props): JSX.Element | null => {
setIsChatboxMenuOpen(false);
};

const toggleFullscreen = () => {
setIsFullscreen(!isFullscreen);
};

const displayPinButton = () => {
if (!pinnedCount) return null;

Expand All @@ -134,6 +147,34 @@ const SideContent = ({ content, item }: Props): JSX.Element | null => {
);
};

const displayFullscreenButton = () => {
// todo: add this to settings (?)
const fullscreen = Boolean(searchParams.get('fullscreen') === 'true');
if (!fullscreen) return null;

return (
<Tooltip
title={
isFullscreen
? t(PLAYER.EXIT_FULLSCREEN_TOOLTIP)
: t(PLAYER.ENTER_FULLSCREEN_TOOLTIP)
}
>
<StyledIconButton
id={ITEM_FULLSCREEN_BUTTON_ID}
aria-label={
isFullscreen
? t(PLAYER.EXIT_FULLSCREEN_TOOLTIP)
: t(PLAYER.ENTER_FULLSCREEN_TOOLTIP)
}
onClick={toggleFullscreen}
>
{isFullscreen ? <ExitFullscreenIcon /> : <EnterFullscreenIcon />}
</StyledIconButton>
</Tooltip>
);
};

const displayChatButton = () => {
if (!settings?.showChatbox) return null;

Expand Down Expand Up @@ -190,21 +231,26 @@ const SideContent = ({ content, item }: Props): JSX.Element | null => {
};

return (
<div>
<Fullscreen
enabled={isFullscreen}
onChange={(isFullscreenEnabled) => setIsFullscreen(isFullscreenEnabled)}
>
{displayChatbox()}
{displayPinnedItems()}
<Grid id="contentGrid">
<StyledMain
isShifted={isChatboxMenuOpen || (isPinnedMenuOpen && pinnedCount > 0)}
>
{displayFullscreenButton()}

{displayChatButton()}

{displayPinButton()}

{content}
</StyledMain>
</Grid>
</div>
</Fullscreen>
);
};

Expand Down
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6460,6 +6460,7 @@ __metadata:
react: "npm:18.2.0"
react-accessible-treeview: "npm:2.8.3"
react-dom: "npm:18.2.0"
react-fullscreen-crossbrowser: "npm:1.1.3"
react-ga4: "npm:2.1.0"
react-i18next: "npm:14.0.5"
react-intersection-observer: "npm:9.8.1"
Expand Down Expand Up @@ -9842,6 +9843,13 @@ __metadata:
languageName: node
linkType: hard

"react-fullscreen-crossbrowser@npm:1.1.3":
version: 1.1.3
resolution: "react-fullscreen-crossbrowser@npm:1.1.3"
checksum: 10/bbf3ae87e22d3049d3605155d33b46632680b9a76d0911433ce245bb3636f52cfc99c0c0e8a1eb251fbcd0f63bdffae90cc3d447f74f1b616ac6e1f147c0b527
languageName: node
linkType: hard

"react-ga4@npm:2.1.0":
version: 2.1.0
resolution: "react-ga4@npm:2.1.0"
Expand Down

0 comments on commit fd230cc

Please sign in to comment.