Merge pull request #40 from Stremio/share-modal

Share modal
This commit is contained in:
Nikola Hristov 2019-04-05 13:36:50 +03:00 committed by GitHub
commit a66823a0de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 207 additions and 209 deletions

View file

@ -1,64 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import Icon, { dataUrl as iconDataUrl } from 'stremio-icons/dom';
import colors from 'stremio-colors';
import styles from './styles';
const renderUrl = (copyToClipboard, url) => {
if (url.length === 0) {
return null;
}
return (
<div className={styles['url-container']}>
<input className={styles['url']} defaultValue={url} readOnly={true} />
<div onClick={copyToClipboard} className={styles['copy-label']}>
<Icon className={styles['copy-icon']} icon={'ic_link'} />Copy
</div>
</div>
);
}
const ShareAddon = (props) => {
const placeholderIconUrl = iconDataUrl({ icon: 'ic_x', fill: colors.surface });
const imageStyle = {
backgroundImage: `url('${placeholderIconUrl}')`
};
return (
<div className={styles['share-addon']}>
<div className={styles['x-container']}>
<div onClick={props.closeModalDialog} style={imageStyle} className={styles['x-icon']} />
</div>
<div className={styles['info-container']}>
<div className={styles['share-label']}>Share Add-on</div>
<div className={styles['buttons']}>
<div onClick={props.shareInFacebook} className={styles['facebook-button']}>
<Icon className={styles['facebook-icon']} icon={'ic_facebook'} />FACEBOOK
</div>
<div onClick={props.shareInTwitter} className={styles['twitter-button']}>
<Icon className={styles['twitter-icon']} icon={'ic_twitter'} />TWITTER
</div>
<div onClick={props.shareInGplus} className={styles['gplus-button']}>
<Icon className={styles['gplus-icon']} icon={'ic_gplus'} />GOOGLE+
</div>
</div>
{renderUrl(props.copyToClipboard, props.url)}
</div>
</div>
);
}
ShareAddon.propTypes = {
url: PropTypes.string.isRequired,
closeModalDialog: PropTypes.func,
shareInFacebook: PropTypes.func,
shareInTwitter: PropTypes.func,
shareInGplus: PropTypes.func,
copyToClipboard: PropTypes.func
};
ShareAddon.defaultProps = {
url: ''
};
export default ShareAddon;

View file

@ -1,3 +0,0 @@
import ShareAddon from './ShareAddon';
export default ShareAddon;

View file

@ -1,136 +0,0 @@
@share-addon-width: 380px;
@spacing: floor((@share-addon-width * 0.06));
.share-addon {
width: @share-addon-width;
padding: ceil((@spacing * 0.5));
.x-icon {
width: ceil((@spacing * 0.5));
height: ceil((@spacing * 0.5));
}
.info-container {
padding: floor((@spacing * 0.3)) ceil((@spacing * 0.9)) @spacing ceil((@spacing * 0.9));
.buttons {
padding: @spacing 0;
}
.facebook-button, .twitter-button, .gplus-button {
width: ceil((@share-addon-width * 0.26));
height: floor((@share-addon-width * 0.09));
.facebook-icon, .twitter-icon, .gplus-icon {
width: ceil((@spacing * 0.6));
height: ceil((@spacing * 0.6));
margin-right: floor((@spacing * 0.3));
}
}
.url-container {
border-radius: 4px;
border-width: 1px;
.url {
font-size: 12px;
border-radius: 4px;
padding: ceil((@spacing * 0.5));
}
.copy-label {
font-size: 14px;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
padding: ceil((@spacing * 0.5));
.copy-icon {
width: ceil((@spacing * 0.7));
height: ceil((@spacing * 0.7));
margin-right: floor((@spacing * 0.3));
}
}
}
}
}
.share-addon {
color: var(--color-surfacelighter);
background-color: var(--color-surfacelighter);
.x-container {
display: flex;
justify-content: flex-end;
.x-icon {
cursor: pointer;
background-position: center;
background-repeat: no-repeat;
}
}
.share-label {
color: var(--color-backgrounddarker);
font-weight: 500;
}
.buttons {
display: flex;
font-size: 11px;
justify-content: space-between;
.facebook-button, .twitter-button, .gplus-button {
display: flex;
cursor: pointer;
align-items: center;
justify-content: center;
.facebook-icon, .twitter-icon, .gplus-icon {
fill: var(--color-surfacelighter);
}
}
.facebook-button {
background-color: var(--color-secondary);
}
.twitter-button {
background-color: var(--color-secondarylighter);
}
.gplus-button {
background-color: var(--color-signal2);
}
}
.url-container {
display: flex;
border-style: solid;
border-color: var(--color-surface);
.url, .copy-label {
color: var(--color-backgrounddarker40);
}
.url {
width: 75%;
outline: none;
font-weight: 600;
text-align: center;
text-overflow: ellipsis;
}
.copy-label {
cursor: pointer;
width: 25%;
font-weight: 500;
display: flex;
justify-content: center;
background-color: var(--color-backgrounddarker20);
.copy-icon {
fill: var(--color-backgrounddarker40);
}
}
}
}

View file

@ -0,0 +1,66 @@
import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { Input, Modal } from 'stremio-common';
import Icon from 'stremio-icons/dom';
import styles from './styles';
const renderInput = ({ className, href, icon, label }) => {
return (
<Input className={classnames(styles['button'], className)} type={'link'} href={href} target={'_blank'}>
<Icon className={styles['icon']} icon={icon} />{label}
</Input>
);
};
const renderUrl = (url) => {
const inputRef = useRef(null);
const copyToClipboard = () => {
inputRef.current.select();
document.execCommand('copy');
};
if (url.length === 0) {
return null;
}
return (
<div className={styles['url-container']}>
<input ref={inputRef} className={styles['url']} type={'text'} tabIndex={'-1'} defaultValue={url} readOnly />
<Input className={styles['copy-button']} type={'button'} onClick={copyToClipboard}>
<Icon className={styles['icon']} icon={'ic_link'} />
<div className={styles['label']}>Copy</div>
</Input>
</div>
);
};
const ShareModal = (props) => {
return (
<Modal>
<div className={styles['share-modal']}>
<Input className={styles['x-container']} type={'button'}>
<Icon className={styles['icon']} icon={'ic_x'} onClick={props.onClose} />
</Input>
<div className={styles['info-container']}>
<div className={styles['share-label']}>Share</div>
<div className={styles['buttons']}>
{renderInput({ className: styles['facebook-button'], href: `https://www.facebook.com/sharer/sharer.php?u=${props.url}`, icon: 'ic_facebook', label: 'FACEBOOK' })}
{renderInput({ className: styles['twitter-button'], href: `https://twitter.com/home?status=${props.url}`, icon: 'ic_twitter', label: 'TWITTER' })}
</div>
{renderUrl(props.url)}
</div>
</div>
</Modal>
);
};
ShareModal.propTypes = {
url: PropTypes.string.isRequired,
onClose: PropTypes.func
};
ShareModal.defaultProps = {
url: ''
};
export default ShareModal;

View file

@ -0,0 +1,3 @@
import ShareModal from './ShareModal';
export default ShareModal;

View file

@ -0,0 +1,131 @@
.share-modal {
--share-modal-width: 350px;
--spacing: 20px;
font-size: 14px;
}
.share-modal {
padding: calc(var(--spacing) * 0.5);
width: var(--share-modal-width);
color: var(--color-surfacelighter);
background-color: var(--color-surfacelighter);
.x-container {
display: flex;
flex-direction: row;
justify-content: flex-end;
.icon {
padding: 0.2em;
width: 1.2em;
height: 1.2em;
fill: var(--color-surfacedark);
cursor: pointer;
&:hover {
fill: var(--color-surface);
}
}
&:focus {
.icon {
background-color: var(--color-surfacelight);
}
}
&:hover {
.icon {
background-color: transparent;
}
}
}
.info-container {
padding: 0 var(--spacing) calc(var(--spacing) * 1.2) var(--spacing);
.share-label {
font-size: 1.1em;
color: var(--color-backgrounddarker);
}
.buttons {
padding: var(--spacing) 0;
display: flex;
flex-direction: row;
.button {
flex: 1;
height: 3.2em;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
font-size: 0.8em;
color: var(--color-surfacelighter);
cursor: pointer;
.icon {
margin-right: 0.6em;
width: 1.4em;
height: 1.4em;
fill: var(--color-surfacelighter);
}
&:focus, &:hover {
filter: brightness(1.2);
}
&:not(:last-child) {
margin-right: 2em;
}
}
.facebook-button {
background-color: var(--color-secondary);
}
.twitter-button {
background-color: var(--color-secondarylighter);
}
}
.url-container {
display: flex;
flex-direction: row;
border: calc(var(--focusable-border-size) * 0.5) solid var(--color-surface);
.url {
flex: 4;
padding: calc(var(--spacing) * 0.5);
font-size: 0.9em;
text-align: center;
color: var(--color-surfacedark);
}
.copy-button {
flex: 1;
padding: calc(var(--spacing) * 0.5);
display: flex;
flex-direction: row;
justify-content: center;
background-color: var(--color-surface);
cursor: pointer;
.icon {
margin-right: 0.4em;
width: 1em;
height: 1em;
fill: var(--color-surfacedarker);
}
.label {
color: var(--color-surfacedarker);
}
&:focus, &:hover {
background-color: var(--color-surface60);
}
}
}
}
}

View file

@ -7,7 +7,7 @@ import Popup from './Popup';
import Router from './Router';
import NavBar from './NavBar';
import MetaItem from './MetaItem';
import ShareAddon from './ShareAddon';
import ShareModal from './ShareModal';
import UserPanel from './UserPanel';
import Loader from './Loader';
@ -21,7 +21,7 @@ export {
withModalsContainer,
Router,
MetaItem,
ShareAddon,
ShareModal,
UserPanel,
Loader,
Slider,

View file

@ -1,6 +1,6 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { Checkbox, MetaItem, ShareAddon, UserPanel, FocusableProvider } from 'stremio-common';
import { Checkbox, LibraryItemList, MetaItem, ShareModal, UserPanel } from 'stremio-common';
import Addon from '../src/routes/Addons/Addon';
import Video from '../src/routes/Detail/VideosList/Video';
import VideosList from '../src/routes/Detail/VideosList';
@ -187,10 +187,11 @@ storiesOf('MetaItem', module)
</div>
));
storiesOf('ShareAddon', module)
.add('share addon', () => (
storiesOf('ShareModal', module)
.add('share modal', () => (
<div style={storyStyle} className={appStyles['app']}>
<ShareAddon url={'....'} />
<ShareModal url={'....'} />
</div>
));