mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-11 17:15:48 +00:00
refactor: use chips instead of multiselect for library filters
This commit is contained in:
parent
1c57dd3a65
commit
1cf2339a35
16 changed files with 321 additions and 69 deletions
129
package-lock.json
generated
129
package-lock.json
generated
|
|
@ -63,6 +63,8 @@
|
||||||
"postcss-loader": "6.2.0",
|
"postcss-loader": "6.2.0",
|
||||||
"readdirp": "3.6.0",
|
"readdirp": "3.6.0",
|
||||||
"terser-webpack-plugin": "5.2.4",
|
"terser-webpack-plugin": "5.2.4",
|
||||||
|
"ts-loader": "^9.5.1",
|
||||||
|
"typescript": "^5.4.2",
|
||||||
"webpack": "5.61.0",
|
"webpack": "5.61.0",
|
||||||
"webpack-cli": "4.9.1",
|
"webpack-cli": "4.9.1",
|
||||||
"webpack-dev-server": "^4.7.4",
|
"webpack-dev-server": "^4.7.4",
|
||||||
|
|
@ -13023,6 +13025,120 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ts-loader": {
|
||||||
|
"version": "9.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz",
|
||||||
|
"integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": "^4.1.0",
|
||||||
|
"enhanced-resolve": "^5.0.0",
|
||||||
|
"micromatch": "^4.0.0",
|
||||||
|
"semver": "^7.3.4",
|
||||||
|
"source-map": "^0.7.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "*",
|
||||||
|
"webpack": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ts-loader/node_modules/ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ts-loader/node_modules/chalk": {
|
||||||
|
"version": "4.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||||
|
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^4.1.0",
|
||||||
|
"supports-color": "^7.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ts-loader/node_modules/color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ts-loader/node_modules/color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/ts-loader/node_modules/has-flag": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ts-loader/node_modules/semver": {
|
||||||
|
"version": "7.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||||
|
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ts-loader/node_modules/source-map": {
|
||||||
|
"version": "0.7.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
||||||
|
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ts-loader/node_modules/supports-color": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "1.14.1",
|
"version": "1.14.1",
|
||||||
"license": "0BSD"
|
"license": "0BSD"
|
||||||
|
|
@ -13077,6 +13193,19 @@
|
||||||
"is-typedarray": "^1.0.0"
|
"is-typedarray": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "5.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz",
|
||||||
|
"integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/unbox-primitive": {
|
"node_modules/unbox-primitive": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,8 @@
|
||||||
"postcss-loader": "6.2.0",
|
"postcss-loader": "6.2.0",
|
||||||
"readdirp": "3.6.0",
|
"readdirp": "3.6.0",
|
||||||
"terser-webpack-plugin": "5.2.4",
|
"terser-webpack-plugin": "5.2.4",
|
||||||
|
"ts-loader": "^9.5.1",
|
||||||
|
"typescript": "^5.4.2",
|
||||||
"webpack": "5.61.0",
|
"webpack": "5.61.0",
|
||||||
"webpack-cli": "4.9.1",
|
"webpack-cli": "4.9.1",
|
||||||
"webpack-dev-server": "^4.7.4",
|
"webpack-dev-server": "^4.7.4",
|
||||||
|
|
|
||||||
34
src/common/Chips/Chip/Chip.less
Normal file
34
src/common/Chips/Chip/Chip.less
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright (C) 2017-2024 Smart code 203358507
|
||||||
|
|
||||||
|
@height: 2.75rem;
|
||||||
|
|
||||||
|
.chip {
|
||||||
|
flex: none;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: @height;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--primary-foreground-color);
|
||||||
|
white-space: nowrap;
|
||||||
|
text-transform: capitalize;
|
||||||
|
padding: 0 1.5rem;
|
||||||
|
border-radius: @height;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
background-color: transparent;
|
||||||
|
user-select: none;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--overlay-color);
|
||||||
|
transition: background-color 0.1s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
font-weight: 600;
|
||||||
|
background-color: var(--primary-accent-color);
|
||||||
|
transition: background-color 0.1s ease-in;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/common/Chips/Chip/Chip.tsx
Normal file
45
src/common/Chips/Chip/Chip.tsx
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright (C) 2017-2024 Smart code 203358507
|
||||||
|
|
||||||
|
import React, { MouseEvent, memo, useCallback, useEffect, useRef } from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import Button from 'stremio/common/Button';
|
||||||
|
import styles from './Chip.less';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
label: string,
|
||||||
|
value: string,
|
||||||
|
active: boolean,
|
||||||
|
onSelect: (value: string) => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Chip = memo(({ label, value, active, onSelect }: Props) => {
|
||||||
|
const ref = useRef<HTMLElement>(null);
|
||||||
|
|
||||||
|
const onClick = useCallback(({ currentTarget }: MouseEvent<HTMLElement>) => {
|
||||||
|
const value = currentTarget.dataset['value'];
|
||||||
|
value && onSelect(value);
|
||||||
|
}, [onselect]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
active && ref.current?.scrollIntoView({
|
||||||
|
block: 'nearest',
|
||||||
|
inline: 'center',
|
||||||
|
behavior: 'smooth',
|
||||||
|
});
|
||||||
|
}, [active]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
ref={ref}
|
||||||
|
key={value}
|
||||||
|
className={classNames(styles['chip'], { [styles['active']]: active })}
|
||||||
|
tabIndex={-1}
|
||||||
|
data-value={value}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Chip;
|
||||||
4
src/common/Chips/Chip/index.ts
Normal file
4
src/common/Chips/Chip/index.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
// Copyright (C) 2017-2024 Smart code 203358507
|
||||||
|
|
||||||
|
import Chip from './Chip';
|
||||||
|
export default Chip;
|
||||||
25
src/common/Chips/Chips.less
Normal file
25
src/common/Chips/Chips.less
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright (C) 2017-2024 Smart code 203358507
|
||||||
|
|
||||||
|
@mask-width: 10%;
|
||||||
|
|
||||||
|
.chips {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap: 1rem;
|
||||||
|
overflow-x: auto;
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
mask-image: linear-gradient(90deg, rgba(0, 0, 0, 1) calc(100% - @mask-width), rgba(0, 0, 0, 0) 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
mask-image: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) @mask-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.center {
|
||||||
|
mask-image: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) @mask-width, rgba(0, 0, 0, 1) calc(100% - @mask-width), rgba(0, 0, 0, 0) 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
51
src/common/Chips/Chips.tsx
Normal file
51
src/common/Chips/Chips.tsx
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright (C) 2017-2024 Smart code 203358507
|
||||||
|
|
||||||
|
import React, { memo, useEffect, useRef, useState } from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import Chip from './Chip';
|
||||||
|
import styles from './Chips.less';
|
||||||
|
|
||||||
|
type Option = {
|
||||||
|
label: string,
|
||||||
|
value: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
options: Option[],
|
||||||
|
selected: string[],
|
||||||
|
onSelect: (value: string) => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const Chips = memo(({ options, selected, onSelect }: Props) => {
|
||||||
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
const [scrollPosition, setScrollPosition] = useState('left');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const onScroll = ({ target }: Event) => {
|
||||||
|
const { scrollLeft, scrollWidth, offsetWidth} = target as HTMLDivElement;
|
||||||
|
const position = scrollLeft === 0 ? 'left' : scrollLeft + offsetWidth >= scrollWidth ? 'right' : 'center';
|
||||||
|
setScrollPosition(position);
|
||||||
|
};
|
||||||
|
|
||||||
|
ref.current?.addEventListener('scroll', onScroll);
|
||||||
|
return () => ref.current?.removeEventListener('scroll', onScroll);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={ref} className={classNames(styles['chips'], [styles[scrollPosition]])}>
|
||||||
|
{
|
||||||
|
options.map(({ label, value }) => (
|
||||||
|
<Chip
|
||||||
|
key={value}
|
||||||
|
label={label}
|
||||||
|
value={value}
|
||||||
|
active={selected.includes(value)}
|
||||||
|
onSelect={onSelect}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Chips;
|
||||||
4
src/common/Chips/index.ts
Normal file
4
src/common/Chips/index.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
// Copyright (C) 2017-2024 Smart code 203358507
|
||||||
|
|
||||||
|
import Chips from './Chips';
|
||||||
|
export default Chips;
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
const AddonDetailsModal = require('./AddonDetailsModal');
|
const AddonDetailsModal = require('./AddonDetailsModal');
|
||||||
const Button = require('./Button');
|
const Button = require('./Button');
|
||||||
const Checkbox = require('./Checkbox');
|
const Checkbox = require('./Checkbox');
|
||||||
|
const { default: Chips } = require('./Chips');
|
||||||
const ColorInput = require('./ColorInput');
|
const ColorInput = require('./ColorInput');
|
||||||
const ContinueWatchingItem = require('./ContinueWatchingItem');
|
const ContinueWatchingItem = require('./ContinueWatchingItem');
|
||||||
const DelayedRenderer = require('./DelayedRenderer');
|
const DelayedRenderer = require('./DelayedRenderer');
|
||||||
|
|
@ -50,6 +51,7 @@ module.exports = {
|
||||||
AddonDetailsModal,
|
AddonDetailsModal,
|
||||||
Button,
|
Button,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
|
Chips,
|
||||||
ColorInput,
|
ColorInput,
|
||||||
ContinueWatchingItem,
|
ContinueWatchingItem,
|
||||||
DelayedRenderer,
|
DelayedRenderer,
|
||||||
|
|
|
||||||
5
src/modules.d.ts
vendored
5
src/modules.d.ts
vendored
|
|
@ -1,2 +1,3 @@
|
||||||
declare module '*';
|
declare module '*.less';
|
||||||
declare module 'classnames';
|
declare module 'stremio/common';
|
||||||
|
declare module 'stremio/common/*';
|
||||||
|
|
@ -3,9 +3,8 @@
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const PropTypes = require('prop-types');
|
const PropTypes = require('prop-types');
|
||||||
const classnames = require('classnames');
|
const classnames = require('classnames');
|
||||||
const { default: Icon } = require('@stremio/stremio-icons/react');
|
|
||||||
const NotFound = require('stremio/routes/NotFound');
|
const NotFound = require('stremio/routes/NotFound');
|
||||||
const { Button, DelayedRenderer, Multiselect, MainNavBars, LibItem, Image, ModalDialog, useProfile, useNotifications, routesRegexp, useOnScrollToBottom, useBinaryState, withCoreSuspender } = require('stremio/common');
|
const { Button, Chips, DelayedRenderer, Multiselect, MainNavBars, LibItem, Image, useProfile, useNotifications, routesRegexp, useOnScrollToBottom, withCoreSuspender } = require('stremio/common');
|
||||||
const useLibrary = require('./useLibrary');
|
const useLibrary = require('./useLibrary');
|
||||||
const useSelectableInputs = require('./useSelectableInputs');
|
const useSelectableInputs = require('./useSelectableInputs');
|
||||||
const styles = require('./styles');
|
const styles = require('./styles');
|
||||||
|
|
@ -49,8 +48,7 @@ const Library = ({ model, urlParams, queryParams }) => {
|
||||||
const profile = useProfile();
|
const profile = useProfile();
|
||||||
const notifications = useNotifications();
|
const notifications = useNotifications();
|
||||||
const [library, loadNextPage] = useLibrary(model, urlParams, queryParams);
|
const [library, loadNextPage] = useLibrary(model, urlParams, queryParams);
|
||||||
const [typeSelect, sortSelect, hasNextPage] = useSelectableInputs(library);
|
const [typeSelect, sortChips, hasNextPage] = useSelectableInputs(library);
|
||||||
const [inputsModalOpen, openInputsModal, closeInputsModal] = useBinaryState(false);
|
|
||||||
const scrollContainerRef = React.useRef(null);
|
const scrollContainerRef = React.useRef(null);
|
||||||
const onScrollToBottom = React.useCallback(() => {
|
const onScrollToBottom = React.useCallback(() => {
|
||||||
if (hasNextPage) {
|
if (hasNextPage) {
|
||||||
|
|
@ -70,11 +68,7 @@ const Library = ({ model, urlParams, queryParams }) => {
|
||||||
model === 'continue_watching' || profile.auth !== null ?
|
model === 'continue_watching' || profile.auth !== null ?
|
||||||
<div className={styles['selectable-inputs-container']}>
|
<div className={styles['selectable-inputs-container']}>
|
||||||
<Multiselect {...typeSelect} className={styles['select-input-container']} />
|
<Multiselect {...typeSelect} className={styles['select-input-container']} />
|
||||||
<Multiselect {...sortSelect} className={styles['select-input-container']} />
|
<Chips {...sortChips} className={styles['select-input-container']} />
|
||||||
<div className={styles['spacing']} />
|
|
||||||
<Button className={styles['filter-container']} title={'All filters'} onClick={openInputsModal}>
|
|
||||||
<Icon className={styles['filter-icon']} name={'filters'} />
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
null
|
null
|
||||||
|
|
@ -122,15 +116,6 @@ const Library = ({ model, urlParams, queryParams }) => {
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
{
|
|
||||||
inputsModalOpen ?
|
|
||||||
<ModalDialog title={'Library filters'} className={styles['selectable-inputs-modal']} onCloseRequest={closeInputsModal}>
|
|
||||||
<Multiselect {...typeSelect} className={styles['select-input-container']} />
|
|
||||||
<Multiselect {...sortSelect} className={styles['select-input-container']} />
|
|
||||||
</ModalDialog>
|
|
||||||
:
|
|
||||||
null
|
|
||||||
}
|
|
||||||
</MainNavBars>
|
</MainNavBars>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -46,28 +46,6 @@
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-container {
|
|
||||||
flex: none;
|
|
||||||
display: none;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 3rem;
|
|
||||||
height: 3rem;
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
background-color: var(--overlay-color);
|
|
||||||
|
|
||||||
.filter-icon {
|
|
||||||
flex: none;
|
|
||||||
width: 1.4rem;
|
|
||||||
height: 1.4rem;
|
|
||||||
color: var(--primary-foreground-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.spacing {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-container {
|
.message-container {
|
||||||
|
|
@ -241,18 +219,6 @@
|
||||||
.library-content {
|
.library-content {
|
||||||
.selectable-inputs-container {
|
.selectable-inputs-container {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
.select-input-container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spacing {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter-container {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta-items-container {
|
.meta-items-container {
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,7 @@ const mapSelectableInputs = (library, t) => {
|
||||||
window.location = event.value;
|
window.location = event.value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const sortSelect = {
|
const sortChips = {
|
||||||
title: t.string('SELECT_SORT'),
|
|
||||||
options: library.selectable.sorts
|
options: library.selectable.sorts
|
||||||
.map(({ sort, deepLinks }) => ({
|
.map(({ sort, deepLinks }) => ({
|
||||||
value: deepLinks.library,
|
value: deepLinks.library,
|
||||||
|
|
@ -28,11 +27,11 @@ const mapSelectableInputs = (library, t) => {
|
||||||
selected: library.selectable.sorts
|
selected: library.selectable.sorts
|
||||||
.filter(({ selected }) => selected)
|
.filter(({ selected }) => selected)
|
||||||
.map(({ deepLinks }) => deepLinks.library),
|
.map(({ deepLinks }) => deepLinks.library),
|
||||||
onSelect: (event) => {
|
onSelect: (value) => {
|
||||||
window.location = event.value;
|
window.location = value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return [typeSelect, sortSelect, library.selectable.nextPage];
|
return [typeSelect, sortChips, library.selectable.nextPage];
|
||||||
};
|
};
|
||||||
|
|
||||||
const useSelectableInputs = (library) => {
|
const useSelectableInputs = (library) => {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const readdirp = require('readdirp');
|
const readdirp = require('readdirp');
|
||||||
|
|
||||||
const COPYRIGHT_HEADER = /^\/\/ Copyright \(C\) 2017-2023 Smart code 203358507.*/;
|
const COPYRIGHT_HEADER = /^\/\/ Copyright \(C\) 2017-\d{4} Smart code 203358507.*/;
|
||||||
|
|
||||||
describe('copyright', () => {
|
describe('copyright', () => {
|
||||||
test('js', async () => {
|
test('js', async () => {
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"lib": ["DOM", "DOM.Iterable"],
|
"lib": ["DOM", "DOM.Iterable"],
|
||||||
"jsx": "preserve",
|
"jsx": "react",
|
||||||
"rootDir": "./src",
|
"baseUrl": "src",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
"paths": {
|
||||||
"stremio/*": ["src/*"],
|
"stremio/*": ["src/*"],
|
||||||
},
|
},
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"checkJs": false,
|
"checkJs": false,
|
||||||
"noEmit": true,
|
"noEmit": false,
|
||||||
"strict": false
|
"strict": true,
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"./src",
|
"src",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,11 @@ module.exports = (env, argv) => ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
test: /\.(ts|tsx)$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: 'ts-loader',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
test: /\.less$/,
|
test: /\.less$/,
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
|
|
@ -142,10 +147,10 @@ module.exports = (env, argv) => ({
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.js', '.json', '.less', '.wasm'],
|
extensions: ['.tsx', '.ts', '.js', '.json', '.less', '.wasm'],
|
||||||
alias: {
|
alias: {
|
||||||
'stremio': path.join(__dirname, 'src'),
|
'stremio': path.resolve(__dirname, 'src'),
|
||||||
'stremio-router': path.join(__dirname, 'src', 'router')
|
'stremio-router': path.resolve(__dirname, 'src', 'router')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
devServer: {
|
devServer: {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue