mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-21 07:32:02 +00:00
Merge branch 'development' of https://github.com/Stremio/stremio-web into refactor/components
This commit is contained in:
commit
ccf593d644
29 changed files with 298 additions and 156 deletions
13
package-lock.json
generated
13
package-lock.json
generated
|
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"name": "stremio",
|
"name": "stremio",
|
||||||
"version": "5.0.0-beta.15",
|
"version": "5.0.0-beta.16",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "stremio",
|
"name": "stremio",
|
||||||
"version": "5.0.0-beta.15",
|
"version": "5.0.0-beta.16",
|
||||||
"license": "gpl-2.0",
|
"license": "gpl-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "7.26.0",
|
"@babel/runtime": "7.26.0",
|
||||||
"@sentry/browser": "8.42.0",
|
"@sentry/browser": "8.42.0",
|
||||||
"@stremio/stremio-colors": "5.2.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-icons": "5.4.1",
|
||||||
"@stremio/stremio-video": "0.0.48",
|
"@stremio/stremio-video": "0.0.48",
|
||||||
"a-color-picker": "1.2.1",
|
"a-color-picker": "1.2.1",
|
||||||
|
|
@ -3371,9 +3371,10 @@
|
||||||
"integrity": "sha512-dYlPgu9W/H7c9s1zmW5tiDnRenaUa4Hg1QCyOg1lhOcgSfM/bVTi5nnqX+IfvGTTUNA0zgzh8hI3o3miwnZxTg=="
|
"integrity": "sha512-dYlPgu9W/H7c9s1zmW5tiDnRenaUa4Hg1QCyOg1lhOcgSfM/bVTi5nnqX+IfvGTTUNA0zgzh8hI3o3miwnZxTg=="
|
||||||
},
|
},
|
||||||
"node_modules/@stremio/stremio-core-web": {
|
"node_modules/@stremio/stremio-core-web": {
|
||||||
"version": "0.48.3",
|
"version": "0.48.4",
|
||||||
"resolved": "https://registry.npmjs.org/@stremio/stremio-core-web/-/stremio-core-web-0.48.3.tgz",
|
"resolved": "https://registry.npmjs.org/@stremio/stremio-core-web/-/stremio-core-web-0.48.4.tgz",
|
||||||
"integrity": "sha512-JL8pOLOEVACYG+33Dtp/mrB2/vuc7RoYZdxX1BQa5MPR8EzsODjpvL5uETmdxo/swgtMZyx2A6/e1B53eKA4oQ==",
|
"integrity": "sha512-848OLm0dtP75aAlYhUB0KoOqwosJIj+ubB8/abuaAzH/N3dtxs40vu2AezmMpGjwR4V60rlOUkUZeWFvrUOjrw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "7.24.1"
|
"@babel/runtime": "7.24.1"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "stremio",
|
"name": "stremio",
|
||||||
"displayName": "Stremio",
|
"displayName": "Stremio",
|
||||||
"version": "5.0.0-beta.15",
|
"version": "5.0.0-beta.16",
|
||||||
"author": "Smart Code OOD",
|
"author": "Smart Code OOD",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "gpl-2.0",
|
"license": "gpl-2.0",
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
"@babel/runtime": "7.26.0",
|
"@babel/runtime": "7.26.0",
|
||||||
"@sentry/browser": "8.42.0",
|
"@sentry/browser": "8.42.0",
|
||||||
"@stremio/stremio-colors": "5.2.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-icons": "5.4.1",
|
||||||
"@stremio/stremio-video": "0.0.48",
|
"@stremio/stremio-video": "0.0.48",
|
||||||
"a-color-picker": "1.2.1",
|
"a-color-picker": "1.2.1",
|
||||||
|
|
|
||||||
|
|
@ -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/common/screen-sizes.less';
|
||||||
@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less';
|
@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less';
|
||||||
|
|
@ -13,6 +13,20 @@
|
||||||
@import (once, less) '~stremio-router/styles.css';
|
@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 {
|
:root {
|
||||||
--landscape-shape-ratio: 0.5625;
|
--landscape-shape-ratio: 0.5625;
|
||||||
--poster-shape-ratio: 1.464;
|
--poster-shape-ratio: 1.464;
|
||||||
|
|
@ -40,6 +54,15 @@
|
||||||
--modal-background-color: rgba(15, 13, 32, 1);
|
--modal-background-color: rgba(15, 13, 32, 1);
|
||||||
--outer-glow: 0px 0px 15px rgba(123, 91, 245, 0.37);
|
--outer-glow: 0px 0px 15px rgba(123, 91, 245, 0.37);
|
||||||
--border-radius: 0.75rem;
|
--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 {
|
html {
|
||||||
width: 100%;
|
width: @html-width;
|
||||||
height: 100%;
|
height: @html-height;
|
||||||
min-width: 640px;
|
min-width: 640px;
|
||||||
min-height: 480px;
|
min-height: 480px;
|
||||||
font-family: 'PlusJakartaSans', 'sans-serif';
|
font-family: 'PlusJakartaSans', 'sans-serif';
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
overscroll-behavior: none;
|
overscroll-behavior: none;
|
||||||
|
user-select: none;
|
||||||
|
touch-action: manipulation;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
|
||||||
body {
|
body {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
@ -106,9 +132,9 @@ html {
|
||||||
|
|
||||||
.toasts-container {
|
.toasts-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: calc(1.2 * var(--horizontal-nav-bar-size));
|
top: calc(1.2 * var(--horizontal-nav-bar-size) + var(--safe-area-inset-top));
|
||||||
right: 0;
|
right: var(--safe-area-inset-right);
|
||||||
bottom: calc(1.2 * var(--horizontal-nav-bar-size));
|
bottom: calc(1.2 * var(--horizontal-nav-bar-size) + var(--calculated-bottom-safe-inset, 0rem));
|
||||||
left: auto;
|
left: auto;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
padding: 0 calc(0.5 * var(--horizontal-nav-bar-size));
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -23,7 +23,6 @@
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
transition: opacity 0.1s ease-out;
|
transition: opacity 0.1s ease-out;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
|
|
||||||
|
|
@ -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/stremio-colors/less/stremio-colors.less';
|
||||||
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
outline-width: var(--focus-outline-size);
|
outline-width: var(--focus-outline-size);
|
||||||
outline-color: @color-surface-light5;
|
outline-color: @color-surface-light5;
|
||||||
outline-offset: calc(-1 * var(--focus-outline-size));
|
outline-offset: calc(-1 * var(--focus-outline-size));
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
padding: 0 1.75rem;
|
padding: 0 1.75rem;
|
||||||
border-radius: @height;
|
border-radius: @height;
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
|
||||||
|
|
@ -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';
|
@import (reference) '~stremio/common/screen-sizes.less';
|
||||||
|
|
||||||
.main-nav-bars-container {
|
.main-nav-bars-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 0;
|
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 {
|
.horizontal-nav-bar {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
@ -17,18 +22,20 @@
|
||||||
.vertical-nav-bar {
|
.vertical-nav-bar {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: var(--horizontal-nav-bar-size);
|
top: var(--horizontal-nav-bar-size);
|
||||||
bottom: 0;
|
bottom: var(--calculated-bottom-safe-inset);
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-content-container {
|
.nav-content-container {
|
||||||
position: absolute;
|
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;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: var(--vertical-nav-bar-size);
|
left: var(--vertical-nav-bar-size);
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,7 +43,7 @@
|
||||||
.main-nav-bars-container {
|
.main-nav-bars-container {
|
||||||
.nav-content-container {
|
.nav-content-container {
|
||||||
left: 0;
|
left: 0;
|
||||||
bottom: var(--vertical-nav-bar-size);
|
padding-bottom: var(--vertical-nav-bar-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vertical-nav-bar {
|
.vertical-nav-bar {
|
||||||
|
|
|
||||||
|
|
@ -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/stremio-colors/less/stremio-colors.less';
|
||||||
@import (reference) '~stremio/common/screen-sizes.less';
|
@import (reference) '~stremio/common/screen-sizes.less';
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
.meta-item-container {
|
.meta-item-container {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
|
|
||||||
&:hover, &:focus, &:global(.active), &:global(.selected) {
|
&:hover, &:focus, &:global(.active), &:global(.selected) {
|
||||||
outline-style: none;
|
outline-style: none;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Copyright (C) 2017-2024 Smart code 203358507
|
// Copyright (C) 2017-2024 Smart code 203358507
|
||||||
|
|
||||||
import React from 'react';
|
import React, { useRef, useEffect, useCallback } from 'react';
|
||||||
import { Button } from 'stremio/components';
|
import { Button } from 'stremio/components';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
@ -19,33 +19,57 @@ type Props = {
|
||||||
|
|
||||||
const Dropdown = ({ level, setLevel, options, onSelect, selectedOption, menuOpen }: Props) => {
|
const Dropdown = ({ level, setLevel, options, onSelect, selectedOption, menuOpen }: Props) => {
|
||||||
const { t } = useTranslation();
|
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 - 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 (
|
return (
|
||||||
<div className={classNames(styles['dropdown'], { [styles['open']]: menuOpen })} role={'listbox'}>
|
<div
|
||||||
{
|
className={classNames(styles['dropdown'], { [styles['open']]: menuOpen })}
|
||||||
level > 0 ?
|
role={'listbox'}
|
||||||
<Button className={styles['back-button']} onClick={onBackButtonClick}>
|
ref={containerRef}
|
||||||
<Icon name={'caret-left'} className={styles['back-button-icon']} />
|
>
|
||||||
{t('BACK')}
|
{level > 0 ?
|
||||||
</Button>
|
<Button className={styles['back-button']} onClick={handleBackClick}>
|
||||||
: null
|
<Icon name={'caret-left'} className={styles['back-button-icon']} />
|
||||||
|
{t('BACK')}
|
||||||
|
</Button>
|
||||||
|
: null
|
||||||
}
|
}
|
||||||
{
|
{options
|
||||||
options
|
.filter((option: MultiselectMenuOption) => !option.hidden)
|
||||||
.filter((option: MultiselectMenuOption) => !option.hidden)
|
.map((option: MultiselectMenuOption) => (
|
||||||
.map((option: MultiselectMenuOption, index) => (
|
<Option
|
||||||
<Option
|
key={option.id}
|
||||||
key={index}
|
ref={handleSetOptionRef(option.value)}
|
||||||
option={option}
|
option={option}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
selectedOption={selectedOption}
|
selectedOption={selectedOption}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Copyright (C) 2017-2024 Smart code 203358507
|
// 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 classNames from 'classnames';
|
||||||
import { Button } from 'stremio/components';
|
import { Button } from 'stremio/components';
|
||||||
import styles from './Option.less';
|
import styles from './Option.less';
|
||||||
|
|
@ -12,7 +12,7 @@ type Props = {
|
||||||
onSelect: (value: number) => void;
|
onSelect: (value: number) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Option = ({ option, selectedOption, onSelect }: Props) => {
|
const Option = forwardRef<HTMLButtonElement, Props>(({ option, selectedOption, onSelect }, ref) => {
|
||||||
// consider using option.id === selectedOption?.id instead
|
// consider using option.id === selectedOption?.id instead
|
||||||
const selected = useMemo(() => option?.value === selectedOption?.value, [option, selectedOption]);
|
const selected = useMemo(() => option?.value === selectedOption?.value, [option, selectedOption]);
|
||||||
|
|
||||||
|
|
@ -22,6 +22,7 @@ const Option = ({ option, selectedOption, onSelect }: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
|
ref={ref}
|
||||||
className={classNames(styles['option'], { [styles['selected']]: selected })}
|
className={classNames(styles['option'], { [styles['selected']]: selected })}
|
||||||
key={option.id}
|
key={option.id}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
|
|
@ -32,7 +33,6 @@ const Option = ({ option, selectedOption, onSelect }: Props) => {
|
||||||
selected && !option.level ?
|
selected && !option.level ?
|
||||||
<div className={styles['icon']} />
|
<div className={styles['icon']} />
|
||||||
: null
|
: null
|
||||||
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
option.level ?
|
option.level ?
|
||||||
|
|
@ -41,6 +41,8 @@ const Option = ({ option, selectedOption, onSelect }: Props) => {
|
||||||
}
|
}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
Option.displayName = 'Option';
|
||||||
|
|
||||||
export default Option;
|
export default Option;
|
||||||
|
|
|
||||||
|
|
@ -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/stremio-colors/less/stremio-colors.less';
|
||||||
@import (reference) '~stremio/common/screen-sizes.less';
|
@import (reference) '~stremio/common/screen-sizes.less';
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
padding-right: 1rem;
|
padding-right: 1rem;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
|
padding-top: var(--safe-area-inset-top);
|
||||||
|
box-sizing: content-box;
|
||||||
|
|
||||||
.logo-container {
|
.logo-container {
|
||||||
flex: none;
|
flex: none;
|
||||||
|
|
@ -32,7 +34,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.back-button-container {
|
.back-button-container {
|
||||||
margin-left: 1rem;
|
margin-left: max(0rem, calc(1rem - var(--safe-area-inset-left)));
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
|
|
||||||
|
|
@ -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/stremio-colors/less/stremio-colors.less';
|
||||||
@import (reference) '~stremio/common/screen-sizes.less';
|
@import (reference) '~stremio/common/screen-sizes.less';
|
||||||
|
|
@ -11,11 +11,13 @@
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
|
|
||||||
&:hover {
|
@media (pointer: fine) {
|
||||||
background-color: var(--overlay-color);
|
&:hover {
|
||||||
|
background-color: var(--overlay-color);
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
outline-width: var(--focus-outline-size);
|
outline-width: var(--focus-outline-size);
|
||||||
outline-color: @color-surface-light5;
|
outline-color: @color-surface-light5;
|
||||||
outline-offset: calc(-1 * var(--focus-outline-size));
|
outline-offset: calc(-1 * var(--focus-outline-size));
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
|
|
||||||
input[type='radio'] {
|
input[type='radio'] {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=0, user-scalable=no, viewport-fit=cover">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-title" content="Stremio">
|
<meta name="apple-mobile-web-app-title" content="Stremio">
|
||||||
<link rel="icon" type="image/x-icon" href="<%= htmlWebpackPlugin.options.faviconsPath %>/favicon.ico">
|
<link rel="icon" type="image/x-icon" href="<%= htmlWebpackPlugin.options.faviconsPath %>/favicon.ico">
|
||||||
|
|
|
||||||
|
|
@ -8,19 +8,43 @@ const { default: Icon } = require('@stremio/stremio-icons/react');
|
||||||
const { Button, Image } = require('stremio/components');
|
const { Button, Image } = require('stremio/components');
|
||||||
const styles = require('./styles');
|
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 { t } = useTranslation();
|
||||||
const toggleButtonOnClick = React.useCallback((event) => {
|
const onInstallClick = React.useCallback((event) => {
|
||||||
if (typeof onToggle === 'function') {
|
event.stopPropagation();
|
||||||
onToggle({
|
if (typeof onInstall === 'function') {
|
||||||
type: 'toggle',
|
onInstall({
|
||||||
|
type: 'install',
|
||||||
nativeEvent: event.nativeEvent,
|
nativeEvent: event.nativeEvent,
|
||||||
reactEvent: event,
|
reactEvent: event,
|
||||||
dataset: dataset
|
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) => {
|
const configureButtonOnClick = React.useCallback((event) => {
|
||||||
|
event.stopPropagation();
|
||||||
if (typeof onConfigure === 'function') {
|
if (typeof onConfigure === 'function') {
|
||||||
onConfigure({
|
onConfigure({
|
||||||
type: 'configure',
|
type: 'configure',
|
||||||
|
|
@ -31,6 +55,7 @@ const Addon = ({ className, id, name, version, logo, description, types, behavio
|
||||||
}
|
}
|
||||||
}, [onConfigure, dataset]);
|
}, [onConfigure, dataset]);
|
||||||
const shareButtonOnClick = React.useCallback((event) => {
|
const shareButtonOnClick = React.useCallback((event) => {
|
||||||
|
event.stopPropagation();
|
||||||
if (typeof onShare === 'function') {
|
if (typeof onShare === 'function') {
|
||||||
onShare({
|
onShare({
|
||||||
type: 'share',
|
type: 'share',
|
||||||
|
|
@ -41,20 +66,15 @@ const Addon = ({ className, id, name, version, logo, description, types, behavio
|
||||||
}
|
}
|
||||||
}, [onShare, dataset]);
|
}, [onShare, dataset]);
|
||||||
const onKeyDown = React.useCallback((event) => {
|
const onKeyDown = React.useCallback((event) => {
|
||||||
if (event.key === 'Enter' && typeof onToggle === 'function') {
|
if (event.key === 'Enter') {
|
||||||
onToggle({
|
onOpenClick(event);
|
||||||
type: 'toggle',
|
|
||||||
nativeEvent: event.nativeEvent,
|
|
||||||
reactEvent: event,
|
|
||||||
dataset: dataset
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, [onToggle, dataset]);
|
}, [onOpenClick]);
|
||||||
const renderLogoFallback = React.useCallback(() => (
|
const renderLogoFallback = React.useCallback(() => (
|
||||||
<Icon className={styles['icon']} name={'addons'} />
|
<Icon className={styles['icon']} name={'addons'} />
|
||||||
), []);
|
), []);
|
||||||
return (
|
return (
|
||||||
<Button className={classnames(className, styles['addon-container'])} onKeyDown={onKeyDown}>
|
<Button className={classnames(className, styles['addon-container'])} onKeyDown={onKeyDown} onClick={onOpenClick}>
|
||||||
<div className={styles['logo-container']}>
|
<div className={styles['logo-container']}>
|
||||||
<Image
|
<Image
|
||||||
className={styles['logo']}
|
className={styles['logo']}
|
||||||
|
|
@ -107,7 +127,7 @@ const Addon = ({ className, id, name, version, logo, description, types, behavio
|
||||||
className={installed ? styles['uninstall-button-container'] : styles['install-button-container']}
|
className={installed ? styles['uninstall-button-container'] : styles['install-button-container']}
|
||||||
title={installed ? t('ADDON_UNINSTALL') : behaviorHints.configurationRequired ? t('ADDON_CONFIGURE') : t('ADDON_INSTALL')}
|
title={installed ? t('ADDON_UNINSTALL') : behaviorHints.configurationRequired ? t('ADDON_CONFIGURE') : t('ADDON_INSTALL')}
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
onClick={!installed && behaviorHints.configurationRequired ? configureButtonOnClick : toggleButtonOnClick}
|
onClick={installed ? onUninstallClick : behaviorHints.configurationRequired ? configureButtonOnClick : onInstallClick}
|
||||||
>
|
>
|
||||||
<div className={styles['label']}>{installed ? t('ADDON_UNINSTALL') : behaviorHints.configurationRequired ? t('ADDON_CONFIGURE') : t('ADDON_INSTALL')}</div>
|
<div className={styles['label']}>{installed ? t('ADDON_UNINSTALL') : behaviorHints.configurationRequired ? t('ADDON_CONFIGURE') : t('ADDON_INSTALL')}</div>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -137,7 +157,10 @@ Addon.propTypes = {
|
||||||
}),
|
}),
|
||||||
installed: PropTypes.bool,
|
installed: PropTypes.bool,
|
||||||
onToggle: PropTypes.func,
|
onToggle: PropTypes.func,
|
||||||
|
onInstall: PropTypes.func,
|
||||||
|
onUninstall: PropTypes.func,
|
||||||
onConfigure: PropTypes.func,
|
onConfigure: PropTypes.func,
|
||||||
|
onOpen: PropTypes.func,
|
||||||
onShare: PropTypes.func,
|
onShare: PropTypes.func,
|
||||||
dataset: PropTypes.object
|
dataset: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,15 @@
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
|
border: 0.15rem solid transparent;
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
background-color: var(--overlay-color);
|
background-color: var(--overlay-color);
|
||||||
cursor: inherit;
|
transition: border-color 0.1s ease-out;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--overlay-color);
|
||||||
|
}
|
||||||
|
|
||||||
.logo-container {
|
.logo-container {
|
||||||
flex: none;
|
flex: none;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ const { useTranslation } = require('react-i18next');
|
||||||
const { default: Icon } = require('@stremio/stremio-icons/react');
|
const { default: Icon } = require('@stremio/stremio-icons/react');
|
||||||
const { usePlatform, useBinaryState, withCoreSuspender } = require('stremio/common');
|
const { usePlatform, useBinaryState, withCoreSuspender } = require('stremio/common');
|
||||||
const { AddonDetailsModal, Button, Image, MainNavBars, Multiselect, ModalDialog, SearchBar, SharePrompt, TextInput } = require('stremio/components');
|
const { AddonDetailsModal, Button, Image, MainNavBars, Multiselect, ModalDialog, SearchBar, SharePrompt, TextInput } = require('stremio/components');
|
||||||
|
const { useServices } = require('stremio/services');
|
||||||
const Addon = require('./Addon');
|
const Addon = require('./Addon');
|
||||||
const useInstalledAddons = require('./useInstalledAddons');
|
const useInstalledAddons = require('./useInstalledAddons');
|
||||||
const useRemoteAddons = require('./useRemoteAddons');
|
const useRemoteAddons = require('./useRemoteAddons');
|
||||||
|
|
@ -18,6 +19,7 @@ const { AddonPlaceholder } = require('./AddonPlaceholder');
|
||||||
const Addons = ({ urlParams, queryParams }) => {
|
const Addons = ({ urlParams, queryParams }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const platform = usePlatform();
|
const platform = usePlatform();
|
||||||
|
const { core } = useServices();
|
||||||
const installedAddons = useInstalledAddons(urlParams);
|
const installedAddons = useInstalledAddons(urlParams);
|
||||||
const remoteAddons = useRemoteAddons(urlParams);
|
const remoteAddons = useRemoteAddons(urlParams);
|
||||||
const [addonDetailsTransportUrl, setAddonDetailsTransportUrl] = useAddonDetailsTransportUrl(urlParams, queryParams);
|
const [addonDetailsTransportUrl, setAddonDetailsTransportUrl] = useAddonDetailsTransportUrl(urlParams, queryParams);
|
||||||
|
|
@ -58,12 +60,30 @@ const Addons = ({ urlParams, queryParams }) => {
|
||||||
const onAddonShare = React.useCallback((event) => {
|
const onAddonShare = React.useCallback((event) => {
|
||||||
setSharedAddon(event.dataset.addon);
|
setSharedAddon(event.dataset.addon);
|
||||||
}, []);
|
}, []);
|
||||||
const onAddonToggle = React.useCallback((event) => {
|
const onAddonInstall = React.useCallback((event) => {
|
||||||
setAddonDetailsTransportUrl(event.dataset.addon.transportUrl);
|
core.transport.dispatch({
|
||||||
}, [setAddonDetailsTransportUrl]);
|
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) => {
|
const onAddonConfigure = React.useCallback((event) => {
|
||||||
platform.openExternal(event.dataset.addon.transportUrl.replace('manifest.json', 'configure'));
|
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(() => {
|
const closeAddonDetails = React.useCallback(() => {
|
||||||
setAddonDetailsTransportUrl(null);
|
setAddonDetailsTransportUrl(null);
|
||||||
}, [setAddonDetailsTransportUrl]);
|
}, [setAddonDetailsTransportUrl]);
|
||||||
|
|
@ -136,8 +156,10 @@ const Addons = ({ urlParams, queryParams }) => {
|
||||||
types={addon.manifest.types}
|
types={addon.manifest.types}
|
||||||
behaviorHints={addon.manifest.behaviorHints}
|
behaviorHints={addon.manifest.behaviorHints}
|
||||||
installed={addon.installed}
|
installed={addon.installed}
|
||||||
onToggle={onAddonToggle}
|
onInstall={onAddonInstall}
|
||||||
|
onUninstall={onAddonUninstall}
|
||||||
onConfigure={onAddonConfigure}
|
onConfigure={onAddonConfigure}
|
||||||
|
onOpen={onAddonOpen}
|
||||||
onShare={onAddonShare}
|
onShare={onAddonShare}
|
||||||
dataset={{ addon }}
|
dataset={{ addon }}
|
||||||
/>
|
/>
|
||||||
|
|
@ -174,8 +196,10 @@ const Addons = ({ urlParams, queryParams }) => {
|
||||||
types={addon.manifest.types}
|
types={addon.manifest.types}
|
||||||
behaviorHints={addon.manifest.behaviorHints}
|
behaviorHints={addon.manifest.behaviorHints}
|
||||||
installed={addon.installed}
|
installed={addon.installed}
|
||||||
onToggle={onAddonToggle}
|
onInstall={onAddonInstall}
|
||||||
|
onUninstall={onAddonUninstall}
|
||||||
onConfigure={onAddonConfigure}
|
onConfigure={onAddonConfigure}
|
||||||
|
onOpen={onAddonOpen}
|
||||||
onShare={onAddonShare}
|
onShare={onAddonShare}
|
||||||
dataset={{ addon }}
|
dataset={{ addon }}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -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/stremio-colors/less/stremio-colors.less';
|
||||||
@import (reference) '~stremio/common/screen-sizes.less';
|
@import (reference) '~stremio/common/screen-sizes.less';
|
||||||
|
|
@ -22,17 +22,22 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.addons-container {
|
.addons-container {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
||||||
.addons-content {
|
.addons-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
margin-bottom: calc(var(--bottom-overlay-size) * -1);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
|
|
||||||
|
.addons-list-container {
|
||||||
|
padding: 0 1.5rem;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.selectable-inputs-container {
|
.selectable-inputs-container {
|
||||||
flex: none;
|
flex: none;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
|
|
@ -41,6 +46,7 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
.add-button-container {
|
.add-button-container {
|
||||||
flex: none;
|
flex: none;
|
||||||
|
|
@ -53,6 +59,7 @@
|
||||||
padding: 0 1.5rem;
|
padding: 0 1.5rem;
|
||||||
border-radius: 3rem;
|
border-radius: 3rem;
|
||||||
background-color: var(--secondary-accent-color);
|
background-color: var(--secondary-accent-color);
|
||||||
|
z-index: 3;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
outline: var(--focus-outline-size) solid var(--secondary-accent-color);
|
outline: var(--focus-outline-size) solid var(--secondary-accent-color);
|
||||||
|
|
@ -133,7 +140,6 @@
|
||||||
.addons-list-container {
|
.addons-list-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
padding: 0 1.5rem;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
.addon {
|
.addon {
|
||||||
|
|
|
||||||
|
|
@ -69,14 +69,17 @@ const Board = () => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case 'Err': {
|
case 'Err': {
|
||||||
return (
|
if (catalog.content.content !== 'EmptyContent') {
|
||||||
<MetaRow
|
return (
|
||||||
key={index}
|
<MetaRow
|
||||||
className={classnames(styles['board-row'], 'animation-fade-in')}
|
key={index}
|
||||||
catalog={catalog}
|
className={classnames(styles['board-row'], 'animation-fade-in')}
|
||||||
message={catalog.content.content}
|
catalog={catalog}
|
||||||
/>
|
message={catalog.content.content}
|
||||||
);
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -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/stremio-colors/less/stremio-colors.less';
|
||||||
@import (reference) '~stremio/common/screen-sizes.less';
|
@import (reference) '~stremio/common/screen-sizes.less';
|
||||||
|
|
@ -23,8 +23,8 @@
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
|
||||||
.board-content {
|
.board-content {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
.board-warning-container {
|
.board-warning-container {
|
||||||
flex: none;
|
flex: none;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
|
margin-bottom: var(--calculated-bottom-safe-inset, 0rem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,15 +192,7 @@
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
|
||||||
.board-content-container {
|
.board-content-container {
|
||||||
&:only-child {
|
|
||||||
.board-content {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.board-content {
|
.board-content {
|
||||||
height: calc(100% - 4rem);
|
|
||||||
|
|
||||||
.board-row {
|
.board-row {
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
@ -226,8 +219,9 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: var(--vertical-nav-bar-size);
|
bottom: calc(var(--vertical-nav-bar-size) + var(--calculated-bottom-safe-inset, 0rem));
|
||||||
height: 4rem;
|
height: 4rem;
|
||||||
|
margin-bottom: 0rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: var(--primary-foreground-color);
|
color: var(--primary-foreground-color);
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
flex: auto;
|
flex: auto;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
transition: background-color 0.1s ease-out;
|
transition: background-color 0.1s ease-out;
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
|
|
||||||
.label, .icon {
|
.label, .icon {
|
||||||
color: var(--primary-foreground-color);
|
color: var(--primary-foreground-color);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: border-color 0.1s ease-out;
|
transition: border-color 0.1s ease-out;
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
border-radius: var(--border-radius) 0 0 0;
|
border-radius: var(--border-radius) 0 0 0;
|
||||||
|
|
|
||||||
|
|
@ -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/stremio-colors/less/stremio-colors.less';
|
||||||
@import (reference) '~stremio/common/screen-sizes.less';
|
@import (reference) '~stremio/common/screen-sizes.less';
|
||||||
|
|
@ -17,13 +17,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.discover-container {
|
.discover-container {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
||||||
.discover-content {
|
.discover-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
margin-bottom: calc(var(--bottom-overlay-size) * -1);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
|
|
@ -32,6 +32,12 @@
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
contain: strict;
|
||||||
|
|
||||||
|
.meta-items-container {
|
||||||
|
padding: 0 1.5rem;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.selectable-inputs-container {
|
.selectable-inputs-container {
|
||||||
flex: none;
|
flex: none;
|
||||||
|
|
@ -40,6 +46,7 @@
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
.select-input {
|
.select-input {
|
||||||
flex: 0 1 15rem;
|
flex: 0 1 15rem;
|
||||||
|
|
@ -162,7 +169,6 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
grid-gap: 0.5rem;
|
grid-gap: 0.5rem;
|
||||||
margin-right: 1.5rem;
|
margin-right: 1.5rem;
|
||||||
padding: 0 1.5rem;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
.meta-item-placeholder {
|
.meta-item-placeholder {
|
||||||
|
|
|
||||||
|
|
@ -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/stremio-colors/less/stremio-colors.less';
|
||||||
@import (reference) '~stremio/common/screen-sizes.less';
|
@import (reference) '~stremio/common/screen-sizes.less';
|
||||||
|
|
@ -13,16 +13,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.library-container {
|
.library-container {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
||||||
.library-content {
|
.library-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
margin-bottom: calc(var(--bottom-overlay-size) * -1);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
.meta-items-container {
|
||||||
|
padding: 0 1.5rem;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.selectable-inputs-container {
|
.selectable-inputs-container {
|
||||||
flex: none;
|
flex: none;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
|
|
@ -30,6 +35,7 @@
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
.select-input-container {
|
.select-input-container {
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
|
|
@ -119,7 +125,6 @@
|
||||||
grid-auto-rows: max-content;
|
grid-auto-rows: max-content;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
grid-gap: 0.5rem;
|
grid-gap: 0.5rem;
|
||||||
padding: 0 1.5rem;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,8 +77,29 @@ const MetaDetails = ({ urlParams, queryParams }) => {
|
||||||
setSeason(event.value);
|
setSeason(event.value);
|
||||||
}, [setSeason]);
|
}, [setSeason]);
|
||||||
const renderBackgroundImageFallback = React.useCallback(() => null, []);
|
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 (
|
return (
|
||||||
<div className={styles['metadetails-container']}>
|
<div className={styles['metadetails-container']}>
|
||||||
|
{
|
||||||
|
renderBackground ?
|
||||||
|
<div className={styles['background-image-layer']}>
|
||||||
|
<Image
|
||||||
|
className={styles['background-image']}
|
||||||
|
src={metaDetails.metaItem.content.content.background}
|
||||||
|
renderFallback={renderBackgroundImageFallback}
|
||||||
|
alt={' '}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
null
|
||||||
|
}
|
||||||
<HorizontalNavBar
|
<HorizontalNavBar
|
||||||
className={styles['nav-bar']}
|
className={styles['nav-bar']}
|
||||||
backButton={true}
|
backButton={true}
|
||||||
|
|
@ -121,20 +142,6 @@ const MetaDetails = ({ urlParams, queryParams }) => {
|
||||||
<MetaPreview.Placeholder className={styles['meta-preview']} />
|
<MetaPreview.Placeholder className={styles['meta-preview']} />
|
||||||
:
|
:
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{
|
|
||||||
typeof metaDetails.metaItem.content.content.background === 'string' &&
|
|
||||||
metaDetails.metaItem.content.content.background.length > 0 ?
|
|
||||||
<div className={styles['background-image-layer']}>
|
|
||||||
<Image
|
|
||||||
className={styles['background-image']}
|
|
||||||
src={metaDetails.metaItem.content.content.background}
|
|
||||||
renderFallback={renderBackgroundImageFallback}
|
|
||||||
alt={' '}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
null
|
|
||||||
}
|
|
||||||
<MetaPreview
|
<MetaPreview
|
||||||
className={classnames(styles['meta-preview'], 'animation-fade-in')}
|
className={classnames(styles['meta-preview'], 'animation-fade-in')}
|
||||||
name={metaDetails.metaItem.content.content.name}
|
name={metaDetails.metaItem.content.content.name}
|
||||||
|
|
|
||||||
|
|
@ -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/stremio-colors/less/stremio-colors.less';
|
||||||
@import (reference) '~stremio/common/screen-sizes.less';
|
@import (reference) '~stremio/common/screen-sizes.less';
|
||||||
|
|
@ -13,6 +13,29 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
padding-left: var(--safe-area-inset-left);
|
||||||
|
padding-right: var(--safe-area-inset-right);
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.background-image-layer {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: -1;
|
||||||
|
background-color: var(--modal-background-color);
|
||||||
|
|
||||||
|
.background-image {
|
||||||
|
pointer-events: none;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: top left;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.nav-bar {
|
.nav-bar {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
@ -27,32 +50,13 @@
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
margin-top: calc(var(--top-overlay-size) * -1);
|
||||||
|
padding-top: var(--top-overlay-size);
|
||||||
|
padding-bottom: var(--calculated-bottom-safe-inset, 0rem);
|
||||||
.vertical-nav-bar {
|
.vertical-nav-bar {
|
||||||
--vertical-nav-bar-size: 6rem;
|
|
||||||
flex: none;
|
flex: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.background-image-layer {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: -1;
|
|
||||||
background-color: var(--modal-background-color);
|
|
||||||
|
|
||||||
.background-image {
|
|
||||||
pointer-events: none;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
object-position: top left;
|
|
||||||
opacity: 0.3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.meta-message-container {
|
.meta-message-container {
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -87,6 +91,8 @@
|
||||||
flex: 0 1 auto;
|
flex: 0 1 auto;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
padding: 0 4rem 2rem 4rem;
|
padding: 0 4rem 2rem 4rem;
|
||||||
|
|
||||||
|
padding-left: max(1rem, calc(4rem - var(--safe-area-inset-left)));
|
||||||
}
|
}
|
||||||
|
|
||||||
.spacing {
|
.spacing {
|
||||||
|
|
|
||||||
|
|
@ -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/stremio-colors/less/stremio-colors.less';
|
||||||
@import (reference) '~stremio/common/screen-sizes.less';
|
@import (reference) '~stremio/common/screen-sizes.less';
|
||||||
|
|
@ -12,13 +12,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-container {
|
.search-container {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
||||||
.search-content {
|
.search-content {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
.search-row {
|
.search-row {
|
||||||
|
|
|
||||||
|
|
@ -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/stremio-colors/less/stremio-colors.less';
|
||||||
@import (reference) '~stremio/common/screen-sizes.less';
|
@import (reference) '~stremio/common/screen-sizes.less';
|
||||||
|
|
@ -13,13 +13,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-container {
|
.settings-container {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
||||||
.settings-content {
|
.settings-content {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue