diff --git a/package-lock.json b/package-lock.json index d6618f1b0..be53e9ec7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,18 @@ { "name": "stremio", - "version": "5.0.0-beta.15", + "version": "5.0.0-beta.16", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "stremio", - "version": "5.0.0-beta.15", + "version": "5.0.0-beta.16", "license": "gpl-2.0", "dependencies": { "@babel/runtime": "7.26.0", "@sentry/browser": "8.42.0", "@stremio/stremio-colors": "5.2.0", - "@stremio/stremio-core-web": "0.48.3", + "@stremio/stremio-core-web": "0.48.4", "@stremio/stremio-icons": "5.4.1", "@stremio/stremio-video": "0.0.48", "a-color-picker": "1.2.1", @@ -3371,9 +3371,10 @@ "integrity": "sha512-dYlPgu9W/H7c9s1zmW5tiDnRenaUa4Hg1QCyOg1lhOcgSfM/bVTi5nnqX+IfvGTTUNA0zgzh8hI3o3miwnZxTg==" }, "node_modules/@stremio/stremio-core-web": { - "version": "0.48.3", - "resolved": "https://registry.npmjs.org/@stremio/stremio-core-web/-/stremio-core-web-0.48.3.tgz", - "integrity": "sha512-JL8pOLOEVACYG+33Dtp/mrB2/vuc7RoYZdxX1BQa5MPR8EzsODjpvL5uETmdxo/swgtMZyx2A6/e1B53eKA4oQ==", + "version": "0.48.4", + "resolved": "https://registry.npmjs.org/@stremio/stremio-core-web/-/stremio-core-web-0.48.4.tgz", + "integrity": "sha512-848OLm0dtP75aAlYhUB0KoOqwosJIj+ubB8/abuaAzH/N3dtxs40vu2AezmMpGjwR4V60rlOUkUZeWFvrUOjrw==", + "license": "MIT", "dependencies": { "@babel/runtime": "7.24.1" } diff --git a/package.json b/package.json index f79244edd..79593f9d5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "stremio", "displayName": "Stremio", - "version": "5.0.0-beta.15", + "version": "5.0.0-beta.16", "author": "Smart Code OOD", "private": true, "license": "gpl-2.0", @@ -16,7 +16,7 @@ "@babel/runtime": "7.26.0", "@sentry/browser": "8.42.0", "@stremio/stremio-colors": "5.2.0", - "@stremio/stremio-core-web": "0.48.3", + "@stremio/stremio-core-web": "0.48.4", "@stremio/stremio-icons": "5.4.1", "@stremio/stremio-video": "0.0.48", "a-color-picker": "1.2.1", diff --git a/src/App/styles.less b/src/App/styles.less index edff6e66d..1a1f50dcc 100644 --- a/src/App/styles.less +++ b/src/App/styles.less @@ -1,4 +1,4 @@ -// Copyright (C) 2017-2023 Smart code 203358507 +// Copyright (C) 2017-2024 Smart code 203358507 @import (reference) '~stremio/common/screen-sizes.less'; @import (reference) '~@stremio/stremio-colors/less/stremio-colors.less'; @@ -13,6 +13,20 @@ @import (once, less) '~stremio-router/styles.css'; } +// iOS pads the bottom inset more than needed, so we deduce the actual inset size when using the webapp +@calculated-bottom-safe-inset: ~"min(env(safe-area-inset-bottom, 0rem), max(1rem, calc(100lvh - 100svh - env(safe-area-inset-top, 0rem))))"; +@html-width: ~"calc(max(100svw, 100dvw))"; +@html-height: ~"calc(max(100svh, 100dvh))"; +@safe-area-inset-top: env(safe-area-inset-top, 0rem); +@safe-area-inset-right: env(safe-area-inset-right, 0rem); +@safe-area-inset-bottom: env(safe-area-inset-bottom, 0rem); +@safe-area-inset-left: env(safe-area-inset-left, 0rem); + +@top-overlay-size: 5.25rem; +@bottom-overlay-size: 0rem; +@overlap-size: 3rem; +@transparency-grandient-pad: 6rem; + :root { --landscape-shape-ratio: 0.5625; --poster-shape-ratio: 1.464; @@ -40,6 +54,15 @@ --modal-background-color: rgba(15, 13, 32, 1); --outer-glow: 0px 0px 15px rgba(123, 91, 245, 0.37); --border-radius: 0.75rem; + --calculated-bottom-safe-inset: @calculated-bottom-safe-inset; + --top-overlay-size: @top-overlay-size; + --bottom-overlay-size: @bottom-overlay-size; + --overlap-size: @overlap-size; + --transparency-grandient-pad: @transparency-grandient-pad; + --safe-area-inset-top: @safe-area-inset-top; + --safe-area-inset-right: @safe-area-inset-right; + --safe-area-inset-bottom: @safe-area-inset-bottom; + --safe-area-inset-left: @safe-area-inset-left; } * { @@ -85,13 +108,16 @@ svg { } html { - width: 100%; - height: 100%; + width: @html-width; + height: @html-height; min-width: 640px; min-height: 480px; font-family: 'PlusJakartaSans', 'sans-serif'; overflow: auto; overscroll-behavior: none; + user-select: none; + touch-action: manipulation; + -webkit-tap-highlight-color: transparent; body { width: 100%; @@ -106,9 +132,9 @@ html { .toasts-container { position: absolute; - top: calc(1.2 * var(--horizontal-nav-bar-size)); - right: 0; - bottom: calc(1.2 * var(--horizontal-nav-bar-size)); + top: calc(1.2 * var(--horizontal-nav-bar-size) + var(--safe-area-inset-top)); + right: var(--safe-area-inset-right); + bottom: calc(1.2 * var(--horizontal-nav-bar-size) + var(--calculated-bottom-safe-inset, 0rem)); left: auto; z-index: 1; padding: 0 calc(0.5 * var(--horizontal-nav-bar-size)); @@ -193,4 +219,10 @@ html { } } } +} + +@media only screen and (max-width: @minimum) { + :root { + --bottom-overlay-size: 6rem; + } } \ No newline at end of file diff --git a/src/components/BottomSheet/BottomSheet.less b/src/components/BottomSheet/BottomSheet.less index 4ac68ead6..6428e5081 100644 --- a/src/components/BottomSheet/BottomSheet.less +++ b/src/components/BottomSheet/BottomSheet.less @@ -23,7 +23,6 @@ opacity: 0.8; transition: opacity 0.1s ease-out; cursor: pointer; - -webkit-tap-highlight-color: transparent; } .container { diff --git a/src/components/Button/Button.less b/src/components/Button/Button.less index 6baf8b7aa..f6a7bcb4b 100644 --- a/src/components/Button/Button.less +++ b/src/components/Button/Button.less @@ -1,4 +1,4 @@ -// Copyright (C) 2017-2023 Smart code 203358507 +// Copyright (C) 2017-2024 Smart code 203358507 @import (reference) '~@stremio/stremio-colors/less/stremio-colors.less'; @@ -6,7 +6,6 @@ outline-width: var(--focus-outline-size); outline-color: @color-surface-light5; outline-offset: calc(-1 * var(--focus-outline-size)); - -webkit-tap-highlight-color: transparent; cursor: pointer; &:focus { diff --git a/src/components/Chips/Chip/Chip.less b/src/components/Chips/Chip/Chip.less index b71a7b6b6..4261f35e9 100644 --- a/src/components/Chips/Chip/Chip.less +++ b/src/components/Chips/Chip/Chip.less @@ -16,7 +16,6 @@ text-transform: capitalize; padding: 0 1.75rem; border-radius: @height; - -webkit-tap-highlight-color: transparent; background-color: transparent; user-select: none; overflow: hidden; diff --git a/src/components/MainNavBars/MainNavBars.less b/src/components/MainNavBars/MainNavBars.less index e76192fbb..2ee57b505 100644 --- a/src/components/MainNavBars/MainNavBars.less +++ b/src/components/MainNavBars/MainNavBars.less @@ -1,10 +1,15 @@ -// Copyright (C) 2017-2023 Smart code 203358507 +// Copyright (C) 2017-2024 Smart code 203358507 @import (reference) '~stremio/common/screen-sizes.less'; .main-nav-bars-container { position: relative; z-index: 0; + overflow: clip; + margin-left: env(safe-area-inset-left, 0px); + margin-right: env(safe-area-inset-right, 0px); + width: calc(100% - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px)); + height: 100%; .horizontal-nav-bar { position: absolute; @@ -17,18 +22,20 @@ .vertical-nav-bar { position: absolute; top: var(--horizontal-nav-bar-size); - bottom: 0; + bottom: var(--calculated-bottom-safe-inset); left: 0; z-index: 1; } .nav-content-container { position: absolute; - top: var(--horizontal-nav-bar-size); + padding-top: calc(var(--horizontal-nav-bar-size) + env(safe-area-inset-top, 0px)); + top: 0; right: 0; bottom: 0; left: var(--vertical-nav-bar-size); z-index: 0; + overflow: scroll; } } @@ -36,7 +43,7 @@ .main-nav-bars-container { .nav-content-container { left: 0; - bottom: var(--vertical-nav-bar-size); + padding-bottom: var(--vertical-nav-bar-size); } .vertical-nav-bar { diff --git a/src/components/MetaItem/styles.less b/src/components/MetaItem/styles.less index 089ef1c21..359525b28 100644 --- a/src/components/MetaItem/styles.less +++ b/src/components/MetaItem/styles.less @@ -1,4 +1,4 @@ -// Copyright (C) 2017-2023 Smart code 203358507 +// Copyright (C) 2017-2024 Smart code 203358507 @import (reference) '~@stremio/stremio-colors/less/stremio-colors.less'; @import (reference) '~stremio/common/screen-sizes.less'; @@ -18,7 +18,6 @@ .meta-item-container { padding: 1rem; overflow: visible; - -webkit-tap-highlight-color: transparent; &:hover, &:focus, &:global(.active), &:global(.selected) { outline-style: none; diff --git a/src/components/MultiselectMenu/Dropdown/Dropdown.tsx b/src/components/MultiselectMenu/Dropdown/Dropdown.tsx index b58582271..3da75619b 100644 --- a/src/components/MultiselectMenu/Dropdown/Dropdown.tsx +++ b/src/components/MultiselectMenu/Dropdown/Dropdown.tsx @@ -1,6 +1,6 @@ // Copyright (C) 2017-2024 Smart code 203358507 -import React from 'react'; +import React, { useRef, useEffect, useCallback } from 'react'; import { Button } from 'stremio/components'; import { useTranslation } from 'react-i18next'; import classNames from 'classnames'; @@ -19,33 +19,57 @@ type Props = { const Dropdown = ({ level, setLevel, options, onSelect, selectedOption, menuOpen }: Props) => { const { t } = useTranslation(); + const optionsRef = useRef(new Map()); + const containerRef = useRef(null); - const onBackButtonClick = () => { + const handleSetOptionRef = useCallback((value: number) => (node: HTMLButtonElement | null) => { + if (node) { + optionsRef.current.set(value, node); + } else { + optionsRef.current.delete(value); + } + }, []); + + const handleBackClick = useCallback(() => { setLevel(level - 1); - }; + }, [setLevel, level]); + + useEffect(() => { + if (menuOpen && selectedOption && containerRef.current) { + const selectedNode = optionsRef.current.get(selectedOption.value); + if (selectedNode) { + selectedNode.scrollIntoView({ + behavior: 'smooth', + block: 'nearest' + }); + } + } + }, [menuOpen, selectedOption]); return ( -
- { - level > 0 ? - - : null +
+ {level > 0 ? + + : null } - { - options - .filter((option: MultiselectMenuOption) => !option.hidden) - .map((option: MultiselectMenuOption, index) => ( -
); diff --git a/src/components/MultiselectMenu/Dropdown/Option/Option.tsx b/src/components/MultiselectMenu/Dropdown/Option/Option.tsx index 877bebc72..91aa173f7 100644 --- a/src/components/MultiselectMenu/Dropdown/Option/Option.tsx +++ b/src/components/MultiselectMenu/Dropdown/Option/Option.tsx @@ -1,6 +1,6 @@ // Copyright (C) 2017-2024 Smart code 203358507 -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback, useMemo, forwardRef } from 'react'; import classNames from 'classnames'; import { Button } from 'stremio/components'; import styles from './Option.less'; @@ -12,7 +12,7 @@ type Props = { onSelect: (value: number) => void; }; -const Option = ({ option, selectedOption, onSelect }: Props) => { +const Option = forwardRef(({ option, selectedOption, onSelect }, ref) => { // consider using option.id === selectedOption?.id instead const selected = useMemo(() => option?.value === selectedOption?.value, [option, selectedOption]); @@ -22,6 +22,7 @@ const Option = ({ option, selectedOption, onSelect }: Props) => { return ( ); -}; +}); + +Option.displayName = 'Option'; export default Option; diff --git a/src/components/NavBar/HorizontalNavBar/styles.less b/src/components/NavBar/HorizontalNavBar/styles.less index 2be5ccf35..512788855 100644 --- a/src/components/NavBar/HorizontalNavBar/styles.less +++ b/src/components/NavBar/HorizontalNavBar/styles.less @@ -1,4 +1,4 @@ -// Copyright (C) 2017-2023 Smart code 203358507 +// Copyright (C) 2017-2024 Smart code 203358507 @import (reference) '~@stremio/stremio-colors/less/stremio-colors.less'; @import (reference) '~stremio/common/screen-sizes.less'; @@ -12,6 +12,8 @@ padding-right: 1rem; background-color: transparent; overflow: visible; + padding-top: var(--safe-area-inset-top); + box-sizing: content-box; .logo-container { flex: none; @@ -32,7 +34,7 @@ } .back-button-container { - margin-left: 1rem; + margin-left: max(0rem, calc(1rem - var(--safe-area-inset-left))); } .title { diff --git a/src/components/NavBar/VerticalNavBar/NavTabButton/styles.less b/src/components/NavBar/VerticalNavBar/NavTabButton/styles.less index 01fd993e3..99592189d 100644 --- a/src/components/NavBar/VerticalNavBar/NavTabButton/styles.less +++ b/src/components/NavBar/VerticalNavBar/NavTabButton/styles.less @@ -1,4 +1,4 @@ -// Copyright (C) 2017-2023 Smart code 203358507 +// Copyright (C) 2017-2024 Smart code 203358507 @import (reference) '~@stremio/stremio-colors/less/stremio-colors.less'; @import (reference) '~stremio/common/screen-sizes.less'; @@ -11,11 +11,13 @@ background-color: transparent; border-radius: 0.75rem; - &:hover { - background-color: var(--overlay-color); + @media (pointer: fine) { + &:hover { + background-color: var(--overlay-color); - .label { - opacity: 0.6; + .label { + opacity: 0.6; + } } } diff --git a/src/components/RadioButton/RadioButton.less b/src/components/RadioButton/RadioButton.less index 4f3380147..7e414a521 100644 --- a/src/components/RadioButton/RadioButton.less +++ b/src/components/RadioButton/RadioButton.less @@ -24,7 +24,6 @@ outline-width: var(--focus-outline-size); outline-color: @color-surface-light5; outline-offset: calc(-1 * var(--focus-outline-size)); - -webkit-tap-highlight-color: transparent; input[type='radio'] { opacity: 0; diff --git a/src/index.html b/src/index.html index 6b9e62fe4..ba8a9e795 100644 --- a/src/index.html +++ b/src/index.html @@ -3,7 +3,7 @@ - + diff --git a/src/routes/Addons/Addon/Addon.js b/src/routes/Addons/Addon/Addon.js index 0b1687465..e2182243a 100644 --- a/src/routes/Addons/Addon/Addon.js +++ b/src/routes/Addons/Addon/Addon.js @@ -8,19 +8,43 @@ const { default: Icon } = require('@stremio/stremio-icons/react'); const { Button, Image } = require('stremio/components'); const styles = require('./styles'); -const Addon = ({ className, id, name, version, logo, description, types, behaviorHints, installed, onToggle, onConfigure, onShare, dataset }) => { +const Addon = ({ className, id, name, version, logo, description, types, behaviorHints, installed, onInstall, onUninstall, onConfigure, onOpen, onShare, dataset }) => { const { t } = useTranslation(); - const toggleButtonOnClick = React.useCallback((event) => { - if (typeof onToggle === 'function') { - onToggle({ - type: 'toggle', + const onInstallClick = React.useCallback((event) => { + event.stopPropagation(); + if (typeof onInstall === 'function') { + onInstall({ + type: 'install', nativeEvent: event.nativeEvent, reactEvent: event, dataset: dataset }); } - }, [onToggle, dataset]); + }, [onInstall, dataset]); + const onUninstallClick = React.useCallback((event) => { + event.stopPropagation(); + if (typeof onUninstall === 'function') { + onUninstall({ + type: 'uninstall', + nativeEvent: event.nativeEvent, + reactEvent: event, + dataset: dataset + }); + } + }, [onUninstall, dataset]); + const onOpenClick = React.useCallback((event) => { + event.stopPropagation(); + if (typeof onOpen === 'function') { + onOpen({ + type: 'open', + nativeEvent: event.nativeEvent, + reactEvent: event, + dataset: dataset + }); + } + }, [onOpen, dataset]); const configureButtonOnClick = React.useCallback((event) => { + event.stopPropagation(); if (typeof onConfigure === 'function') { onConfigure({ type: 'configure', @@ -31,6 +55,7 @@ const Addon = ({ className, id, name, version, logo, description, types, behavio } }, [onConfigure, dataset]); const shareButtonOnClick = React.useCallback((event) => { + event.stopPropagation(); if (typeof onShare === 'function') { onShare({ type: 'share', @@ -41,20 +66,15 @@ const Addon = ({ className, id, name, version, logo, description, types, behavio } }, [onShare, dataset]); const onKeyDown = React.useCallback((event) => { - if (event.key === 'Enter' && typeof onToggle === 'function') { - onToggle({ - type: 'toggle', - nativeEvent: event.nativeEvent, - reactEvent: event, - dataset: dataset - }); + if (event.key === 'Enter') { + onOpenClick(event); } - }, [onToggle, dataset]); + }, [onOpenClick]); const renderLogoFallback = React.useCallback(() => ( ), []); return ( - @@ -137,7 +157,10 @@ Addon.propTypes = { }), installed: PropTypes.bool, onToggle: PropTypes.func, + onInstall: PropTypes.func, + onUninstall: PropTypes.func, onConfigure: PropTypes.func, + onOpen: PropTypes.func, onShare: PropTypes.func, dataset: PropTypes.object }; diff --git a/src/routes/Addons/Addon/styles.less b/src/routes/Addons/Addon/styles.less index 26863df3f..a3bb4e174 100644 --- a/src/routes/Addons/Addon/styles.less +++ b/src/routes/Addons/Addon/styles.less @@ -8,9 +8,15 @@ flex-direction: row; align-items: flex-start; padding: 1.5rem; + border: 0.15rem solid transparent; border-radius: var(--border-radius); background-color: var(--overlay-color); - cursor: inherit; + transition: border-color 0.1s ease-out; + cursor: pointer; + + &:hover { + border-color: var(--overlay-color); + } .logo-container { flex: none; diff --git a/src/routes/Addons/Addons.js b/src/routes/Addons/Addons.js index 2ceb5b4fb..91bcbd27f 100644 --- a/src/routes/Addons/Addons.js +++ b/src/routes/Addons/Addons.js @@ -7,6 +7,7 @@ const { useTranslation } = require('react-i18next'); const { default: Icon } = require('@stremio/stremio-icons/react'); const { usePlatform, useBinaryState, withCoreSuspender } = require('stremio/common'); const { AddonDetailsModal, Button, Image, MainNavBars, Multiselect, ModalDialog, SearchBar, SharePrompt, TextInput } = require('stremio/components'); +const { useServices } = require('stremio/services'); const Addon = require('./Addon'); const useInstalledAddons = require('./useInstalledAddons'); const useRemoteAddons = require('./useRemoteAddons'); @@ -18,6 +19,7 @@ const { AddonPlaceholder } = require('./AddonPlaceholder'); const Addons = ({ urlParams, queryParams }) => { const { t } = useTranslation(); const platform = usePlatform(); + const { core } = useServices(); const installedAddons = useInstalledAddons(urlParams); const remoteAddons = useRemoteAddons(urlParams); const [addonDetailsTransportUrl, setAddonDetailsTransportUrl] = useAddonDetailsTransportUrl(urlParams, queryParams); @@ -58,12 +60,30 @@ const Addons = ({ urlParams, queryParams }) => { const onAddonShare = React.useCallback((event) => { setSharedAddon(event.dataset.addon); }, []); - const onAddonToggle = React.useCallback((event) => { - setAddonDetailsTransportUrl(event.dataset.addon.transportUrl); - }, [setAddonDetailsTransportUrl]); + const onAddonInstall = React.useCallback((event) => { + core.transport.dispatch({ + action: 'Ctx', + args: { + action: 'InstallAddon', + args: event.dataset.addon, + } + }); + }, []); + const onAddonUninstall = React.useCallback((event) => { + core.transport.dispatch({ + action: 'Ctx', + args: { + action: 'UninstallAddon', + args: event.dataset.addon, + } + }); + }, []); const onAddonConfigure = React.useCallback((event) => { platform.openExternal(event.dataset.addon.transportUrl.replace('manifest.json', 'configure')); }, []); + const onAddonOpen = React.useCallback((event) => { + setAddonDetailsTransportUrl(event.dataset.addon.transportUrl); + }, [setAddonDetailsTransportUrl]); const closeAddonDetails = React.useCallback(() => { setAddonDetailsTransportUrl(null); }, [setAddonDetailsTransportUrl]); @@ -136,8 +156,10 @@ const Addons = ({ urlParams, queryParams }) => { types={addon.manifest.types} behaviorHints={addon.manifest.behaviorHints} installed={addon.installed} - onToggle={onAddonToggle} + onInstall={onAddonInstall} + onUninstall={onAddonUninstall} onConfigure={onAddonConfigure} + onOpen={onAddonOpen} onShare={onAddonShare} dataset={{ addon }} /> @@ -174,8 +196,10 @@ const Addons = ({ urlParams, queryParams }) => { types={addon.manifest.types} behaviorHints={addon.manifest.behaviorHints} installed={addon.installed} - onToggle={onAddonToggle} + onInstall={onAddonInstall} + onUninstall={onAddonUninstall} onConfigure={onAddonConfigure} + onOpen={onAddonOpen} onShare={onAddonShare} dataset={{ addon }} /> diff --git a/src/routes/Addons/styles.less b/src/routes/Addons/styles.less index 8e53ac07c..37152eb8f 100644 --- a/src/routes/Addons/styles.less +++ b/src/routes/Addons/styles.less @@ -1,4 +1,4 @@ -// Copyright (C) 2017-2023 Smart code 203358507 +// Copyright (C) 2017-2024 Smart code 203358507 @import (reference) '~@stremio/stremio-colors/less/stremio-colors.less'; @import (reference) '~stremio/common/screen-sizes.less'; @@ -22,17 +22,22 @@ } .addons-container { - width: 100%; height: 100%; background-color: transparent; .addons-content { width: 100%; height: 100%; + margin-bottom: calc(var(--bottom-overlay-size) * -1); display: flex; flex-direction: column; align-self: stretch; + .addons-list-container { + padding: 0 1.5rem; + z-index: 1; + } + .selectable-inputs-container { flex: none; align-self: stretch; @@ -41,6 +46,7 @@ justify-content: space-between; padding: 1.5rem; overflow: visible; + z-index: 2; .add-button-container { flex: none; @@ -53,6 +59,7 @@ padding: 0 1.5rem; border-radius: 3rem; background-color: var(--secondary-accent-color); + z-index: 3; &:hover { outline: var(--focus-outline-size) solid var(--secondary-accent-color); @@ -133,7 +140,6 @@ .addons-list-container { flex: 1; align-self: stretch; - padding: 0 1.5rem; overflow-y: auto; .addon { diff --git a/src/routes/Board/Board.js b/src/routes/Board/Board.js index d78e212c3..a9ed6b553 100644 --- a/src/routes/Board/Board.js +++ b/src/routes/Board/Board.js @@ -69,14 +69,17 @@ const Board = () => { ); } case 'Err': { - return ( - - ); + if (catalog.content.content !== 'EmptyContent') { + return ( + + ); + } + return null; } default: { return ( diff --git a/src/routes/Board/styles.less b/src/routes/Board/styles.less index d410a35c0..403e75869 100644 --- a/src/routes/Board/styles.less +++ b/src/routes/Board/styles.less @@ -1,4 +1,4 @@ -// Copyright (C) 2017-2023 Smart code 203358507 +// Copyright (C) 2017-2024 Smart code 203358507 @import (reference) '~@stremio/stremio-colors/less/stremio-colors.less'; @import (reference) '~stremio/common/screen-sizes.less'; @@ -23,8 +23,8 @@ background: transparent; .board-content { - width: 100%; height: 100%; + width: 100%; padding: 0 1rem; overflow-y: auto; @@ -38,6 +38,7 @@ .board-warning-container { flex: none; align-self: stretch; + margin-bottom: var(--calculated-bottom-safe-inset, 0rem); } } @@ -191,15 +192,7 @@ z-index: 0; .board-content-container { - &:only-child { - .board-content { - height: 100%; - } - } - .board-content { - height: calc(100% - 4rem); - .board-row { margin-bottom: 1.5rem; } @@ -226,8 +219,9 @@ position: absolute; left: 0; right: 0; - bottom: var(--vertical-nav-bar-size); + bottom: calc(var(--vertical-nav-bar-size) + var(--calculated-bottom-safe-inset, 0rem)); height: 4rem; + margin-bottom: 0rem; } } } \ No newline at end of file diff --git a/src/routes/Calendar/Details/Details.less b/src/routes/Calendar/Details/Details.less index 2e78ca703..db11acc78 100644 --- a/src/routes/Calendar/Details/Details.less +++ b/src/routes/Calendar/Details/Details.less @@ -16,7 +16,6 @@ font-size: 1rem; font-weight: 500; color: var(--primary-foreground-color); - -webkit-tap-highlight-color: transparent; .name { flex: auto; diff --git a/src/routes/Calendar/Selector/Selector.less b/src/routes/Calendar/Selector/Selector.less index 6683697be..d71e10c70 100644 --- a/src/routes/Calendar/Selector/Selector.less +++ b/src/routes/Calendar/Selector/Selector.less @@ -22,7 +22,6 @@ gap: 0.5rem; border-radius: 0.5rem; transition: background-color 0.1s ease-out; - -webkit-tap-highlight-color: transparent; .label, .icon { color: var(--primary-foreground-color); diff --git a/src/routes/Calendar/Table/Cell/Cell.less b/src/routes/Calendar/Table/Cell/Cell.less index 1a0f16d7e..a5c79e178 100644 --- a/src/routes/Calendar/Table/Cell/Cell.less +++ b/src/routes/Calendar/Table/Cell/Cell.less @@ -13,7 +13,6 @@ overflow: hidden; cursor: pointer; transition: border-color 0.1s ease-out; - -webkit-tap-highlight-color: transparent; &:first-child { border-radius: var(--border-radius) 0 0 0; diff --git a/src/routes/Discover/styles.less b/src/routes/Discover/styles.less index 7460d1d47..05f03baf0 100644 --- a/src/routes/Discover/styles.less +++ b/src/routes/Discover/styles.less @@ -1,4 +1,4 @@ -// Copyright (C) 2017-2023 Smart code 203358507 +// Copyright (C) 2017-2024 Smart code 203358507 @import (reference) '~@stremio/stremio-colors/less/stremio-colors.less'; @import (reference) '~stremio/common/screen-sizes.less'; @@ -17,13 +17,13 @@ } .discover-container { - width: 100%; height: 100%; background-color: transparent; .discover-content { width: 100%; height: 100%; + margin-bottom: calc(var(--bottom-overlay-size) * -1); display: flex; flex-direction: row; @@ -32,6 +32,12 @@ align-self: stretch; display: flex; flex-direction: column; + contain: strict; + + .meta-items-container { + padding: 0 1.5rem; + z-index: 1; + } .selectable-inputs-container { flex: none; @@ -40,6 +46,7 @@ flex-direction: row; padding: 1.5rem; overflow: visible; + z-index: 2; .select-input { flex: 0 1 15rem; @@ -162,7 +169,6 @@ align-items: center; grid-gap: 0.5rem; margin-right: 1.5rem; - padding: 0 1.5rem; overflow-y: auto; .meta-item-placeholder { diff --git a/src/routes/Library/styles.less b/src/routes/Library/styles.less index e6cf97ffa..6719932e1 100644 --- a/src/routes/Library/styles.less +++ b/src/routes/Library/styles.less @@ -1,4 +1,4 @@ -// Copyright (C) 2017-2023 Smart code 203358507 +// Copyright (C) 2017-2024 Smart code 203358507 @import (reference) '~@stremio/stremio-colors/less/stremio-colors.less'; @import (reference) '~stremio/common/screen-sizes.less'; @@ -13,16 +13,21 @@ } .library-container { - width: 100%; height: 100%; background-color: transparent; .library-content { width: 100%; height: 100%; + margin-bottom: calc(var(--bottom-overlay-size) * -1); display: flex; flex-direction: column; + .meta-items-container { + padding: 0 1.5rem; + z-index: 1; + } + .selectable-inputs-container { flex: none; align-self: stretch; @@ -30,6 +35,7 @@ flex-direction: row; padding: 1.5rem; overflow: visible; + z-index: 2; .select-input-container { flex-grow: 0; @@ -119,7 +125,6 @@ grid-auto-rows: max-content; align-items: center; grid-gap: 0.5rem; - padding: 0 1.5rem; overflow-y: auto; } } diff --git a/src/routes/MetaDetails/MetaDetails.js b/src/routes/MetaDetails/MetaDetails.js index 79bd03906..24c904cfd 100644 --- a/src/routes/MetaDetails/MetaDetails.js +++ b/src/routes/MetaDetails/MetaDetails.js @@ -77,8 +77,29 @@ const MetaDetails = ({ urlParams, queryParams }) => { setSeason(event.value); }, [setSeason]); const renderBackgroundImageFallback = React.useCallback(() => null, []); + const renderBackground = React.useMemo(() => !!( + metaPath && + metaDetails?.metaItem && + metaDetails.metaItem.content.type !== 'Loading' && + typeof metaDetails.metaItem.content.content?.background === 'string' && + metaDetails.metaItem.content.content.background.length > 0 + ), [metaPath, metaDetails]); + return (
+ { + renderBackground ? +
+ {' +
+ : + null + } { : - { - typeof metaDetails.metaItem.content.content.background === 'string' && - metaDetails.metaItem.content.content.background.length > 0 ? -
- {' -
- : - null - }