add addon prompt implemented

This commit is contained in:
svetlagasheva 2019-10-31 13:06:11 +02:00
parent bb1a4886c3
commit e9745ea905
5 changed files with 172 additions and 8 deletions

View file

@ -64,7 +64,7 @@ const NavMenu = ({ className }) => {
</Button>
<Button className={styles['nav-menu-option-container']} title={'Addons'} href={'#/addons'}>
<Icon className={styles['icon']} icon={'ic_addons'} />
<div className={styles['nav-menu-option-label']}>Addons</div>
<div className={styles['nav-menu-option-label']}>Add-ons</div>
</Button>
<Button className={styles['nav-menu-option-container']} title={'Remote Control'}>
<Icon className={styles['icon']} icon={'ic_remote'} />

View file

@ -1,7 +1,7 @@
const React = require('react');
const classnames = require('classnames');
const Icon = require('stremio-icons/dom');
const { Modal } = require('stremio-router');
const { Modal, useRouteFocused } = require('stremio-router');
const { Button, Multiselect, NavBar, TextInput, SharePrompt } = require('stremio/common');
const Addon = require('./Addon');
const AddonPrompt = require('./AddonPrompt');
@ -10,16 +10,40 @@ const useSelectedAddon = require('./useSelectedAddon');
const styles = require('./styles');
const Addons = ({ urlParams, queryParams }) => {
const inputRef = React.useRef(null);
const focusable = useRouteFocused();
const [query, setQuery] = React.useState('');
const queryOnChange = React.useCallback((event) => {
setQuery(event.currentTarget.value);
}, []);
const [addons, dropdowns, setSelectedAddon, installSelectedAddon, uninstallSelectedAddon, installedAddons] = useAddons(urlParams, queryParams);
const [addedAddon, setAddedAddon] = React.useState(false);
const [selectedAddon, clearSelectedAddon] = useSelectedAddon(queryParams.get('addon'));
const [sharedAddon, setSharedAddon] = React.useState(null);
const onAddAddonButtonClicked = React.useCallback(() => {
setAddedAddon(true);
}, []);
const onAddButtonClicked = React.useCallback(() => {
setSelectedAddon(inputRef.current.value);
setAddedAddon(false);
}, [setSelectedAddon]);
React.useEffect(() => {
const onKeyUp = (event) => {
if (event.key === 'Escape' && typeof close === 'function') {
setAddedAddon(false);
}
};
if (focusable) {
window.addEventListener('keyup', onKeyUp);
}
return () => {
window.removeEventListener('keyup', onKeyUp);
};
}, [close, focusable]);
const promptModalBackgroundOnClick = React.useCallback((event) => {
if (!event.nativeEvent.clearSelectedAddonPrevented) {
clearSelectedAddon();
setAddedAddon(false);
setSharedAddon(null);
}
}, []);
@ -32,12 +56,12 @@ const Addons = ({ urlParams, queryParams }) => {
}, [installedAddons]);
return (
<div className={styles['addons-container']}>
<NavBar className={styles['nav-bar']} backButton={true} title={'Addons'} />
<NavBar className={styles['nav-bar']} backButton={true} title={'Add-ons'} />
<div className={styles['addons-content']}>
<div className={styles['top-bar-container']}>
<Button className={styles['add-button-container']} title={'Add addon'}>
<Button className={styles['add-button-container']} title={'Add add-on'} onClick={onAddAddonButtonClicked}>
<Icon className={styles['icon']} icon={'ic_plus'} />
<div className={styles['add-button-label']}>Add addon</div>
<div className={styles['add-button-label']}>Add add-on</div>
</Button>
{dropdowns.map((dropdown, index) => (
<Multiselect {...dropdown} key={index} className={styles['dropdown']} />
@ -47,7 +71,7 @@ const Addons = ({ urlParams, queryParams }) => {
<TextInput
className={styles['search-input']}
type={'text'}
placeholder={'Search addons...'}
placeholder={'Search add-ons...'}
value={query}
onChange={queryOnChange}
/>
@ -72,6 +96,32 @@ const Addons = ({ urlParams, queryParams }) => {
))
}
</div>
{
addedAddon ?
<Modal className={styles['prompt-modal-container']} onClick={promptModalBackgroundOnClick}>
<div className={classnames(styles['prompt-container'], styles['add-addon-prompt-container'])}>
<div className={classnames(styles['prompt'], styles['add-addon-prompt'])} onClick={promptOnClick}>
<Button className={styles['close-button-container']} title={'Close'} tabIndex={-1} onClick={() => setAddedAddon(false)}>
<Icon className={styles['icon']} icon={'ic_x'} />
</Button>
<div className={styles['add-addon-prompt-content']}>
<div className={styles['add-addon-prompt-label']}>Add add-on</div>
<TextInput ref={inputRef} className={styles['url-content']} type={'text'} tabIndex={'-1'} placeholder={'Paste url...'} />
<div className={styles['buttons-container']}>
<Button className={classnames(styles['button-container'], styles['cancel-button'])} title={'Cancel'} onClick={() => setAddedAddon(false)}>
<div className={styles['label']}>Cancel</div>
</Button>
<Button className={classnames(styles['button-container'], styles['add-button'])} title={'Add'} onClick={onAddButtonClicked}>
<div className={styles['label']}>Add</div>
</Button>
</div>
</div>
</div>
</div>
</Modal>
:
null
}
{
selectedAddon !== null ?
<Modal className={styles['prompt-modal-container']} onClick={promptModalBackgroundOnClick}>

View file

@ -138,6 +138,119 @@
}
}
.add-addon-prompt-container {
width: 30rem;
.add-addon-prompt {
position: relative;
z-index: 0;
display: flex;
flex-direction: column;
padding: 2.4rem 0;
background-color: var(--color-surfacelighter);
.close-button-container {
position: absolute;
top: 0.4rem;
right: 0.4rem;
z-index: 1;
width: 2rem;
height: 2rem;
padding: 0.4rem;
&:hover {
background-color: var(--color-surfacelight);
}
.icon {
display: block;
width: 100%;
height: 100%;
fill: var(--color-backgrounddarker);
}
}
.add-addon-prompt-content {
padding: 0 2.4rem;
.add-addon-prompt-label {
margin-bottom: 1.4rem;
font-size: 1.3rem;
color: var(--color-backgrounddarker);
}
.url-content {
flex: 1;
width: 100%;
padding: 0.5rem;
font-size: 0.9rem;
color: var(--color-surfacedark);
border: thin solid var(--color-surface);
}
.buttons-container {
flex: none;
align-self: stretch;
display: flex;
flex-direction: row;
margin-top: 2rem;
.button-container {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
height: 3rem;
padding: 0 1rem;
&:first-child {
margin-right: 2rem;
}
.label {
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
max-height: 2.4em;
font-size: 1.2rem;
text-align: center;
}
}
.cancel-button {
outline-color: var(--color-surfacedark);
outline-style: solid;
&:hover, &:focus {
background-color: var(--color-surfacelight);
}
.label {
color: var(--color-backgrounddarker);
}
}
.add-button {
background-color: var(--color-signal5);
&:hover, &:focus {
filter: brightness(1.2);
}
&:focus {
outline-color: var(--color-surfacedarker);
}
.label {
color: var(--color-surfacelighter);
}
}
}
}
}
}
.addon-prompt-container {
width: 50rem;
}

View file

@ -21,7 +21,8 @@ const useSelectedAddon = (transportUrl) => {
const { pathname, search } = UrlUtils.parse(locationHash.slice(1));
const queryParams = new URLSearchParams(search);
queryParams.delete('addon');
if (!queryParams.values().next().done) {
queryParams.delete('null');
if ([...queryParams].length !== 0) {
window.location.replace(`#${pathname}?${queryParams.toString()}`);
}
else {

View file

@ -31,7 +31,7 @@ const StreamsList = ({ className, metaItem }) => {
</div>
<Button className={styles['install-addons-container']} title={'Install addons'} href={'#/addons'}>
<Icon className={styles['icon']} icon={'ic_addons'} />
<div className={styles['label']}>Install addons</div>
<div className={styles['label']}>Install add-ons</div>
</Button>
</div>
);