Skip to content

Commit

Permalink
fix: make sure the scrollbar is not cropped on all platforms, improve…
Browse files Browse the repository at this point in the history
… immersiveness
  • Loading branch information
IEduStu committed Apr 26, 2024
1 parent 06130ea commit edd2d8d
Show file tree
Hide file tree
Showing 17 changed files with 124 additions and 19 deletions.
10 changes: 9 additions & 1 deletion src/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const { useTranslation } = require('react-i18next');
const { Router } = require('stremio-router');
const { Core, Shell, Chromecast, DragAndDrop, KeyboardShortcuts, ServicesProvider } = require('stremio/services');
const { NotFound } = require('stremio/routes');
const { ToastProvider, TooltipProvider, CONSTANTS, withCoreSuspender } = require('stremio/common');
const { ToastProvider, TooltipProvider, CONSTANTS, withCoreSuspender, platform } = require('stremio/common');
const ServicesToaster = require('./ServicesToaster');
const DeepLinkHandler = require('./DeepLinkHandler');
const SearchParamsHandler = require('./SearchParamsHandler');
Expand Down Expand Up @@ -52,6 +52,14 @@ const App = () => {
window.removeEventListener('hashchange', onLocationHashChange);
};
}, []);
React.useEffect(() => {
// on mobile and macOS the scrollbars aren't visible when they're not being used,
// so we imitate this behavior on those platforms, and fallback to a custom scrollbar on other platforms
const osOverlayScrollbar = platform.isMobile() || platform.isMac();

if (osOverlayScrollbar)
document.documentElement.classList.add('os-overlay-scrollbar');
}, []);
React.useEffect(() => {
const onCoreStateChanged = () => {
setInitialized(
Expand Down
15 changes: 14 additions & 1 deletion src/App/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@
box-shadow: none;
overflow: hidden;
word-break: break-word;

@supports not selector(::-webkit-scrollbar) {
scrollbar-width: thin;
scrollbar-color: var(--overlay-color) transparent;
}
}

html:global(.os-overlay-scrollbar) {
// this makes the browser ignore the custom scrollbar styles when it bahves as an overlay on this platform
// and fallbacks to using the OS scrollbar with the given properties when it's not an overlay scrollbar
scrollbar-width: thin;
scrollbar-color: var(--overlay-color) transparent;
}
Expand Down Expand Up @@ -130,9 +140,12 @@ html {
z-index: 1;
padding: 0 calc(0.5 * var(--horizontal-nav-bar-size));
overflow-y: auto;
scrollbar-width: none;
pointer-events: none;

@supports not selector(::-webkit-scrollbar) {
scrollbar-width: none;
}

&::-webkit-scrollbar {
display: none;
}
Expand Down
7 changes: 4 additions & 3 deletions src/common/MainNavBars/MainNavBars.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const TABS = [
{ id: 'settings', label: 'SETTINGS', icon: 'settings', href: '#/settings' },
];

const MainNavBars = React.memo(({ className, route, query, children }) => {
const MainNavBars = React.memo(({ className, route, query, noOverflow, children }) => {
return (
<div className={classnames(className, styles['main-nav-bars-container'])}>
<HorizontalNavBar
Expand All @@ -32,7 +32,7 @@ const MainNavBars = React.memo(({ className, route, query, children }) => {
selected={route}
tabs={TABS}
/>
<div className={styles['nav-content-container']}>{children}</div>
<div className={classnames(styles['nav-content-container'], {[styles['no-overflow']]: noOverflow})}>{children}</div>
</div>
);
});
Expand All @@ -43,7 +43,8 @@ MainNavBars.propTypes = {
className: PropTypes.string,
route: PropTypes.string,
query: PropTypes.string,
children: PropTypes.node
noOverflow: PropTypes.bool,
children: PropTypes.node,
};

module.exports = MainNavBars;
24 changes: 22 additions & 2 deletions src/common/MainNavBars/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,27 @@

--top-overlay-size: calc(var(--horizontal-nav-bar-size) + var(--safe-area-inset-top, 0px));
--bottom-overlay-size: calc(var(--vertical-nav-bar-size) + var(--calculated-bottom-safe-inset, 0px));
--overlap-size: 3rem;
--transparency-grandient-pad: 6rem;
--overlap-size: 6rem;
--transparency-grandient-pad: 2.5rem;

mask: linear-gradient(
to bottom,
transparent calc(var(--top-overlay-size) - var(--overlap-size)),
rgba(0, 0, 0, 0.08) calc(var(--top-overlay-size) - (var(--overlap-size) / 2)),
rgba(0, 0, 0, 0.16) calc(var(--top-overlay-size) - (var(--overlap-size) / 3)),
black calc(var(--top-overlay-size) + var(--transparency-grandient-pad)),
black 100%
);
overflow-x: hidden;

&::-webkit-scrollbar-track {
margin-top: var(--top-overlay-size);
}

&.no-overflow {
overflow: clip;
overflow: hidden;
}
}
}

Expand All @@ -61,10 +73,18 @@
mask: linear-gradient(
to bottom,
transparent calc(var(--top-overlay-size) - var(--overlap-size)),
rgba(0, 0, 0, 0.08) calc(var(--top-overlay-size) - (var(--overlap-size) / 2)),
rgba(0, 0, 0, 0.16) calc(var(--top-overlay-size) - (var(--overlap-size) / 3)),
black calc(var(--top-overlay-size) + var(--transparency-grandient-pad)),
black calc(100% - var(--bottom-overlay-size) - var(--transparency-grandient-pad)),
rgba(0, 0, 0, 0.16) calc(100% - var(--bottom-overlay-size) + (var(--overlap-size) / 3)),
rgba(0, 0, 0, 0.08) calc(100% - var(--bottom-overlay-size) + (var(--overlap-size) / 2)),
transparent calc(100% - var(--bottom-overlay-size) + var(--overlap-size))
);

&::-webkit-scrollbar-track {
margin-bottom: var(--bottom-overlay-size);
}
}

.vertical-nav-bar {
Expand Down
17 changes: 15 additions & 2 deletions src/common/MetaPreview/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,13 @@
overflow-y: auto;

&:not(:hover) {
scrollbar-color: transparent transparent;
@supports not selector(::-webkit-scrollbar-thumb) {
scrollbar-color: transparent transparent;
}

html:global(.os-overlay-scrollbar) {
scrollbar-color: transparent transparent;
}

&::-webkit-scrollbar-thumb, &::-webkit-scrollbar-track {
background-color: transparent;
Expand Down Expand Up @@ -245,7 +251,14 @@
flex-shrink: 0;
margin-top: 3rem;
overflow: visible;
scrollbar-width: none;

@supports not selector(::-webkit-scrollbar) {
scrollbar-width: none;
}

html:global(.os-overlay-scrollbar) {
scrollbar-width: none;
}

&::-webkit-scrollbar {
display: none;
Expand Down
9 changes: 8 additions & 1 deletion src/common/NavBar/VerticalNavBar/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@
width: var(--vertical-nav-bar-size);
background-color: transparent;
overflow-y: auto;
scrollbar-width: none;

@supports not selector(::-webkit-scrollbar) {
scrollbar-width: none;
}

html:global(.os-overlay-scrollbar) {
scrollbar-width: none;
}

&::-webkit-scrollbar {
display: none;
Expand Down
4 changes: 4 additions & 0 deletions src/common/platform.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ const Bowser = require('bowser');
const browser = Bowser.parse(window.navigator?.userAgent || '');

const name = iOS() ? 'ios' : (browser?.os?.name || 'unknown').toLowerCase();
const osName = browser?.os?.name || 'unknown';

module.exports = {
name,
isMobile: () => {
return name === 'ios' || name === 'android';
},
isMac: () => {
return osName === 'macOS';
}
};
2 changes: 1 addition & 1 deletion src/routes/Addons/Addons.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const Addons = ({ urlParams, queryParams }) => {
clearSharedAddon();
}, [urlParams, queryParams]);
return (
<MainNavBars className={styles['addons-container']} route={'addons'}>
<MainNavBars className={styles['addons-container']} route={'addons'} noOverflow>
<div className={styles['addons-content']}>
<div className={styles['selectable-inputs-container']}>
{selectInputs.map((selectInput, index) => (
Expand Down
9 changes: 8 additions & 1 deletion src/routes/Addons/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
--top-overlay-size: var(--selectable-inputs-assumed-height);
--bottom-vertical-nav-bar-size: 0px;
--bottom-overlay-size: var(--bottom-vertical-nav-bar-size);
--overlap-size: 2.5rem;
--overlap-size: 6rem;
--transparency-grandient-pad: 3rem;

width: 100%;
Expand All @@ -50,10 +50,17 @@
mask: linear-gradient(
to bottom,
transparent calc(var(--top-overlay-size) - var(--overlap-size)),
rgba(0, 0, 0, 0.08) calc(var(--top-overlay-size) - (var(--overlap-size) / 2)),
rgba(0, 0, 0, 0.16) calc(var(--top-overlay-size) - (var(--overlap-size) / 3)),
black calc(var(--top-overlay-size) + var(--transparency-grandient-pad)),
black 100%
);
z-index: 1;

&::-webkit-scrollbar-track {
margin-top: var(--selectable-inputs-assumed-height);
margin-bottom: var(--bottom-overlay-size);
}
}

.selectable-inputs-container {
Expand Down
2 changes: 1 addition & 1 deletion src/routes/Discover/Discover.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const Discover = ({ urlParams, queryParams }) => {
setSelectedMetaItemIndex(0);
}, [discover.selected]);
return (
<MainNavBars className={styles['discover-container']} route={'discover'}>
<MainNavBars className={styles['discover-container']} route={'discover'} noOverflow>
<div className={styles['discover-content']}>
<div className={styles['catalog-container']}>
<div className={styles['selectable-inputs-container']}>
Expand Down
9 changes: 8 additions & 1 deletion src/routes/Discover/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
--top-overlay-size: var(--selectable-inputs-assumed-height);
--bottom-vertical-nav-bar-size: 0px;
--bottom-overlay-size: var(--bottom-vertical-nav-bar-size);
--overlap-size: 3rem;
--overlap-size: 6rem;
--transparency-grandient-pad: 6rem;

width: 100%;
Expand All @@ -58,10 +58,17 @@
mask: linear-gradient(
to bottom,
transparent calc(var(--top-overlay-size) - var(--overlap-size)),
rgba(0, 0, 0, 0.08) calc(var(--top-overlay-size) - (var(--overlap-size) / 2)),
rgba(0, 0, 0, 0.16) calc(var(--top-overlay-size) - (var(--overlap-size) / 3)),
black calc(var(--top-overlay-size) + var(--transparency-grandient-pad)),
black 100%
);
z-index: 1;

&::-webkit-scrollbar-track {
margin-top: var(--selectable-inputs-assumed-height);
margin-bottom: var(--bottom-overlay-size);
}
}

.selectable-inputs-container {
Expand Down
2 changes: 1 addition & 1 deletion src/routes/Library/Library.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const Library = ({ model, urlParams, queryParams }) => {
}
}, [profile.auth, library.selected]);
return (
<MainNavBars className={styles['library-container']} route={model}>
<MainNavBars className={styles['library-container']} route={model} noOverflow>
<div className={styles['library-content']}>
{
model === 'continue_watching' || profile.auth !== null ?
Expand Down
9 changes: 8 additions & 1 deletion src/routes/Library/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
--top-overlay-size: var(--selectable-inputs-assumed-height);
--bottom-vertical-nav-bar-size: 0px;
--bottom-overlay-size: var(--bottom-vertical-nav-bar-size);
--overlap-size: 3rem;
--overlap-size: 6rem;
--transparency-grandient-pad: 6rem;

width: 100%;
Expand All @@ -40,10 +40,17 @@
mask: linear-gradient(
to bottom,
transparent calc(var(--top-overlay-size) - var(--overlap-size)),
rgba(0, 0, 0, 0.08) calc(var(--top-overlay-size) - (var(--overlap-size) / 2)),
rgba(0, 0, 0, 0.16) calc(var(--top-overlay-size) - (var(--overlap-size) / 3)),
black calc(var(--top-overlay-size) + var(--transparency-grandient-pad)),
black 100%
);
z-index: 1;

&::-webkit-scrollbar-track {
margin-top: var(--selectable-inputs-assumed-height);
margin-bottom: var(--bottom-overlay-size);
}
}

.selectable-inputs-container {
Expand Down
9 changes: 8 additions & 1 deletion src/routes/MetaDetails/StreamsList/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,14 @@

.streams-container {
margin-top: 0;
scrollbar-color: @color-surface-light5-20 transparent;

@supports not selector(::-webkit-scrollbar-thumb) {
scrollbar-color: @color-surface-light5-20 transparent;
}

html:global(.os-overlay-scrollbar) {
scrollbar-color: @color-surface-light5-20 transparent;
}

&::-webkit-scrollbar-thumb {
background-color: @color-surface-light5-20;
Expand Down
8 changes: 7 additions & 1 deletion src/routes/MetaDetails/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

--navbar-assumed-height: 84px;
--top-overlay-size: var(--navbar-assumed-height);
--overlap-size: 3rem;
--overlap-size: 6rem;
--transparency-grandient-pad: 6rem;

.background-image-layer {
Expand Down Expand Up @@ -68,10 +68,16 @@
mask: linear-gradient(
to bottom,
transparent calc(var(--top-overlay-size) - var(--overlap-size)),
rgba(0, 0, 0, 0.08) calc(var(--top-overlay-size) - (var(--overlap-size) / 2)),
rgba(0, 0, 0, 0.16) calc(var(--top-overlay-size) - (var(--overlap-size) / 3)),
black calc(var(--top-overlay-size) + var(--transparency-grandient-pad)),
black 100%
);

&::-webkit-scrollbar-track {
margin-top: var(--navbar-assumed-height);
}

.vertical-nav-bar {
--vertical-nav-bar-size: 6rem;
flex: none;
Expand Down
2 changes: 1 addition & 1 deletion src/routes/Settings/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ const Settings = () => {
closeConfigureServerUrlModal();
}, [routeFocused]);
return (
<MainNavBars className={styles['settings-container']} route={'settings'}>
<MainNavBars className={styles['settings-container']} route={'settings'} noOverflow>
<div className={classnames(styles['settings-content'], 'animation-fade-in')}>
<div className={styles['side-menu-container']}>
<Button className={classnames(styles['side-menu-button'], { [styles['selected']]: selectedSectionId === GENERAL_SECTION })} title={ t('SETTINGS_NAV_GENERAL') } data-section={GENERAL_SECTION} onClick={sideMenuButtonOnClick}>
Expand Down
5 changes: 5 additions & 0 deletions src/routes/Settings/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@
scroll-padding-top: var(--top-overlay-size);
isolation: isolate;

&::-webkit-scrollbar-track {
margin-top: var(--top-overlay-size);
margin-bottom: var(--bottom-overlay-size);
}

.section-container {
display: flex;
flex-direction: column;
Expand Down

0 comments on commit edd2d8d

Please sign in to comment.