mirror of
https://github.com/mediacms-io/mediacms.git
synced 2026-06-08 01:42:37 -04:00
feat: Implement persistent "Embed Mode" to hide UI shell via Session Storage (#1484)
* initial implementation * updates in ViewerInfoVideoTitleBanner component * Implement persistent "Embed Mode" to hide UI shell via Session Storage --------- Co-authored-by: Yiannis <1515939+styiannis@users.noreply.github.com>
This commit is contained in:
@@ -1,101 +1,103 @@
|
||||
import React, { createContext, useContext, useEffect, useState } from 'react';
|
||||
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { BrowserCache } from '../classes/';
|
||||
import { PageStore } from '../stores/';
|
||||
import { addClassname, removeClassname } from '../helpers/';
|
||||
import { addClassname, removeClassname, inEmbeddedApp } from '../helpers/';
|
||||
import SiteContext from './SiteContext';
|
||||
|
||||
let slidingSidebarTimeout;
|
||||
|
||||
function onSidebarVisibilityChange(visibleSidebar) {
|
||||
clearTimeout(slidingSidebarTimeout);
|
||||
clearTimeout(slidingSidebarTimeout);
|
||||
|
||||
addClassname(document.body, 'sliding-sidebar');
|
||||
|
||||
slidingSidebarTimeout = setTimeout(function () {
|
||||
if ('media' === PageStore.get('current-page')) {
|
||||
if (visibleSidebar) {
|
||||
addClassname(document.body, 'overflow-hidden');
|
||||
} else {
|
||||
removeClassname(document.body, 'overflow-hidden');
|
||||
}
|
||||
} else {
|
||||
if (!visibleSidebar || 767 < window.innerWidth) {
|
||||
removeClassname(document.body, 'overflow-hidden');
|
||||
} else {
|
||||
addClassname(document.body, 'overflow-hidden');
|
||||
}
|
||||
}
|
||||
|
||||
if (visibleSidebar) {
|
||||
addClassname(document.body, 'visible-sidebar');
|
||||
} else {
|
||||
removeClassname(document.body, 'visible-sidebar');
|
||||
}
|
||||
addClassname(document.body, 'sliding-sidebar');
|
||||
|
||||
slidingSidebarTimeout = setTimeout(function () {
|
||||
slidingSidebarTimeout = null;
|
||||
removeClassname(document.body, 'sliding-sidebar');
|
||||
}, 220);
|
||||
}, 20);
|
||||
if ('media' === PageStore.get('current-page')) {
|
||||
if (visibleSidebar) {
|
||||
addClassname(document.body, 'overflow-hidden');
|
||||
} else {
|
||||
removeClassname(document.body, 'overflow-hidden');
|
||||
}
|
||||
} else {
|
||||
if (!visibleSidebar || 767 < window.innerWidth) {
|
||||
removeClassname(document.body, 'overflow-hidden');
|
||||
} else {
|
||||
addClassname(document.body, 'overflow-hidden');
|
||||
}
|
||||
}
|
||||
|
||||
if (visibleSidebar) {
|
||||
addClassname(document.body, 'visible-sidebar');
|
||||
} else {
|
||||
removeClassname(document.body, 'visible-sidebar');
|
||||
}
|
||||
|
||||
slidingSidebarTimeout = setTimeout(function () {
|
||||
slidingSidebarTimeout = null;
|
||||
removeClassname(document.body, 'sliding-sidebar');
|
||||
}, 220);
|
||||
}, 20);
|
||||
}
|
||||
|
||||
export const LayoutContext = createContext();
|
||||
|
||||
export const LayoutProvider = ({ children }) => {
|
||||
const site = useContext(SiteContext);
|
||||
const cache = new BrowserCache('MediaCMS[' + site.id + '][layout]', 86400);
|
||||
const site = useContext(SiteContext);
|
||||
const cache = new BrowserCache('MediaCMS[' + site.id + '][layout]', 86400);
|
||||
|
||||
const enabledSidebar = !!(document.getElementById('app-sidebar') || document.querySelector('.page-sidebar'));
|
||||
const isMediaPage = useMemo(() => PageStore.get('current-page') === 'media', []);
|
||||
const isEmbeddedApp = useMemo(() => inEmbeddedApp(), []);
|
||||
|
||||
const [visibleSidebar, setVisibleSidebar] = useState(cache.get('visible-sidebar'));
|
||||
const [visibleMobileSearch, setVisibleMobileSearch] = useState(false);
|
||||
const enabledSidebar = Boolean(document.getElementById('app-sidebar') || document.querySelector('.page-sidebar'));
|
||||
|
||||
const toggleMobileSearch = () => {
|
||||
setVisibleMobileSearch(!visibleMobileSearch);
|
||||
};
|
||||
const [visibleSidebar, setVisibleSidebar] = useState(cache.get('visible-sidebar'));
|
||||
const [visibleMobileSearch, setVisibleMobileSearch] = useState(false);
|
||||
|
||||
const toggleSidebar = () => {
|
||||
const newval = !visibleSidebar;
|
||||
onSidebarVisibilityChange(newval);
|
||||
setVisibleSidebar(newval);
|
||||
};
|
||||
const toggleMobileSearch = () => {
|
||||
setVisibleMobileSearch(!visibleMobileSearch);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (visibleSidebar) {
|
||||
addClassname(document.body, 'visible-sidebar');
|
||||
} else {
|
||||
removeClassname(document.body, 'visible-sidebar');
|
||||
}
|
||||
if ('media' !== PageStore.get('current-page') && 1023 < window.innerWidth) {
|
||||
cache.set('visible-sidebar', visibleSidebar);
|
||||
}
|
||||
}, [visibleSidebar]);
|
||||
const toggleSidebar = () => {
|
||||
const newval = !visibleSidebar;
|
||||
onSidebarVisibilityChange(newval);
|
||||
setVisibleSidebar(newval);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
PageStore.once('page_init', () => {
|
||||
if ('media' === PageStore.get('current-page')) {
|
||||
setVisibleSidebar(false);
|
||||
removeClassname(document.body, 'visible-sidebar');
|
||||
}
|
||||
});
|
||||
useEffect(() => {
|
||||
if (!isEmbeddedApp && visibleSidebar) {
|
||||
addClassname(document.body, 'visible-sidebar');
|
||||
} else {
|
||||
removeClassname(document.body, 'visible-sidebar');
|
||||
}
|
||||
|
||||
setVisibleSidebar(
|
||||
'media' !== PageStore.get('current-page') &&
|
||||
1023 < window.innerWidth &&
|
||||
(null === visibleSidebar || visibleSidebar)
|
||||
);
|
||||
}, []);
|
||||
if (!isEmbeddedApp && !isMediaPage && 1023 < window.innerWidth) {
|
||||
cache.set('visible-sidebar', visibleSidebar);
|
||||
}
|
||||
}, [isEmbeddedApp, isMediaPage, visibleSidebar]);
|
||||
|
||||
const value = {
|
||||
enabledSidebar,
|
||||
visibleSidebar,
|
||||
setVisibleSidebar,
|
||||
visibleMobileSearch,
|
||||
toggleMobileSearch,
|
||||
toggleSidebar,
|
||||
};
|
||||
useEffect(() => {
|
||||
PageStore.once('page_init', () => {
|
||||
if (isEmbeddedApp || isMediaPage) {
|
||||
setVisibleSidebar(false);
|
||||
removeClassname(document.body, 'visible-sidebar');
|
||||
}
|
||||
});
|
||||
|
||||
return <LayoutContext.Provider value={value}>{children}</LayoutContext.Provider>;
|
||||
setVisibleSidebar(
|
||||
!isEmbeddedApp && !isMediaPage && 1023 < window.innerWidth && (null === visibleSidebar || visibleSidebar)
|
||||
);
|
||||
}, []);
|
||||
|
||||
const value = {
|
||||
enabledSidebar,
|
||||
visibleSidebar,
|
||||
setVisibleSidebar,
|
||||
visibleMobileSearch,
|
||||
toggleMobileSearch,
|
||||
toggleSidebar,
|
||||
};
|
||||
|
||||
return <LayoutContext.Provider value={value}>{children}</LayoutContext.Provider>;
|
||||
};
|
||||
|
||||
export const LayoutConsumer = LayoutContext.Consumer;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
export function inEmbeddedApp() {
|
||||
try {
|
||||
const params = new URL(globalThis.location.href).searchParams;
|
||||
const mode = params.get('mode');
|
||||
|
||||
if (mode === 'embed_mode') {
|
||||
sessionStorage.setItem('media_cms_embed_mode', 'true');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mode === 'standard') {
|
||||
sessionStorage.removeItem('media_cms_embed_mode');
|
||||
return false;
|
||||
}
|
||||
|
||||
return sessionStorage.getItem('media_cms_embed_mode') === 'true';
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -14,3 +14,4 @@ export * from './quickSort';
|
||||
export * from './requests';
|
||||
export { translateString } from './translate';
|
||||
export { replaceString } from './replacementStrings';
|
||||
export * from './embeddedApp';
|
||||
|
||||
@@ -3,64 +3,83 @@ import ReactDOM from 'react-dom';
|
||||
import { ThemeProvider } from './contexts/ThemeContext';
|
||||
import { LayoutProvider } from './contexts/LayoutContext';
|
||||
import { UserProvider } from './contexts/UserContext';
|
||||
import { inEmbeddedApp } from './helpers';
|
||||
|
||||
const AppProviders = ({ children }) => (
|
||||
<LayoutProvider>
|
||||
<ThemeProvider>
|
||||
<UserProvider>{children}</UserProvider>
|
||||
</ThemeProvider>
|
||||
</LayoutProvider>
|
||||
<LayoutProvider>
|
||||
<ThemeProvider>
|
||||
<UserProvider>{children}</UserProvider>
|
||||
</ThemeProvider>
|
||||
</LayoutProvider>
|
||||
);
|
||||
|
||||
import { PageHeader, PageSidebar } from '../components/page-layout';
|
||||
|
||||
export function renderPage(idSelector, PageComponent) {
|
||||
const appHeader = document.getElementById('app-header');
|
||||
const appSidebar = document.getElementById('app-sidebar');
|
||||
const appContent = idSelector ? document.getElementById(idSelector) : undefined;
|
||||
if (inEmbeddedApp()) {
|
||||
globalThis.document.body.classList.add('embedded-app');
|
||||
globalThis.document.body.classList.remove('visible-sidebar');
|
||||
|
||||
if (appContent && PageComponent) {
|
||||
ReactDOM.render(
|
||||
<AppProviders>
|
||||
{appHeader ? ReactDOM.createPortal(<PageHeader />, appHeader) : null}
|
||||
{appSidebar ? ReactDOM.createPortal(<PageSidebar />, appSidebar) : null}
|
||||
<PageComponent />
|
||||
</AppProviders>,
|
||||
appContent
|
||||
);
|
||||
} else if (appHeader && appSidebar) {
|
||||
ReactDOM.render(
|
||||
<AppProviders>
|
||||
{ReactDOM.createPortal(<PageHeader />, appHeader)}
|
||||
<PageSidebar />
|
||||
</AppProviders>,
|
||||
appSidebar
|
||||
);
|
||||
} else if (appHeader) {
|
||||
ReactDOM.render(
|
||||
<LayoutProvider>
|
||||
<ThemeProvider>
|
||||
<UserProvider>
|
||||
<PageHeader />
|
||||
</UserProvider>
|
||||
</ThemeProvider>
|
||||
</LayoutProvider>,
|
||||
appSidebar
|
||||
);
|
||||
} else if (appSidebar) {
|
||||
ReactDOM.render(
|
||||
<AppProviders>
|
||||
<PageSidebar />
|
||||
</AppProviders>,
|
||||
appSidebar
|
||||
);
|
||||
}
|
||||
const appContent = idSelector ? document.getElementById(idSelector) : undefined;
|
||||
|
||||
if (appContent && PageComponent) {
|
||||
ReactDOM.render(
|
||||
<AppProviders>
|
||||
<PageComponent />
|
||||
</AppProviders>,
|
||||
appContent
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const appContent = idSelector ? document.getElementById(idSelector) : undefined;
|
||||
const appHeader = document.getElementById('app-header');
|
||||
const appSidebar = document.getElementById('app-sidebar');
|
||||
|
||||
if (appContent && PageComponent) {
|
||||
ReactDOM.render(
|
||||
<AppProviders>
|
||||
{appHeader ? ReactDOM.createPortal(<PageHeader />, appHeader) : null}
|
||||
{appSidebar ? ReactDOM.createPortal(<PageSidebar />, appSidebar) : null}
|
||||
<PageComponent />
|
||||
</AppProviders>,
|
||||
appContent
|
||||
);
|
||||
} else if (appHeader && appSidebar) {
|
||||
ReactDOM.render(
|
||||
<AppProviders>
|
||||
{ReactDOM.createPortal(<PageHeader />, appHeader)}
|
||||
<PageSidebar />
|
||||
</AppProviders>,
|
||||
appSidebar
|
||||
);
|
||||
} else if (appHeader) {
|
||||
ReactDOM.render(
|
||||
<LayoutProvider>
|
||||
<ThemeProvider>
|
||||
<UserProvider>
|
||||
<PageHeader />
|
||||
</UserProvider>
|
||||
</ThemeProvider>
|
||||
</LayoutProvider>,
|
||||
appSidebar
|
||||
);
|
||||
} else if (appSidebar) {
|
||||
ReactDOM.render(
|
||||
<AppProviders>
|
||||
<PageSidebar />
|
||||
</AppProviders>,
|
||||
appSidebar
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function renderEmbedPage(idSelector, PageComponent) {
|
||||
const appContent = idSelector ? document.getElementById(idSelector) : undefined;
|
||||
const appContent = idSelector ? document.getElementById(idSelector) : undefined;
|
||||
|
||||
if (appContent && PageComponent) {
|
||||
ReactDOM.render(<PageComponent />, appContent);
|
||||
}
|
||||
if (appContent && PageComponent) {
|
||||
ReactDOM.render(<PageComponent />, appContent);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user