mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-08-16 15:44:49 +00:00
Merge pull request #70 from Stremio/user-notifications-menu
User notifications menu
This commit is contained in:
commit
f9203087a2
22 changed files with 611 additions and 2 deletions
|
|
@ -17,6 +17,7 @@ const MainNavBar = ({ className }) => {
|
|||
searchBar={true}
|
||||
addonsButton={true}
|
||||
fullscreenButton={true}
|
||||
notificationsMenu={true}
|
||||
navMenu={true}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@ const NavTabButton = require('./NavTabButton');
|
|||
const SearchBar = require('./SearchBar');
|
||||
const AddonsButton = require('./AddonsButton');
|
||||
const FullscreenButton = require('./FullscreenButton');
|
||||
const NotificationsMenu = require('./NotificationsMenu');
|
||||
const NavMenu = require('./NavMenu');
|
||||
const styles = require('./styles');
|
||||
|
||||
const NavBar = React.memo(({ className, backButton, tabs, title, searchBar, addonsButton, fullscreenButton, navMenu }) => {
|
||||
const NavBar = React.memo(({ className, backButton, tabs, title, searchBar, addonsButton, fullscreenButton, notificationsMenu, navMenu }) => {
|
||||
const backButtonOnClick = React.useCallback(() => {
|
||||
window.history.back();
|
||||
}, []);
|
||||
|
|
@ -62,6 +63,12 @@ const NavBar = React.memo(({ className, backButton, tabs, title, searchBar, addo
|
|||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
notificationsMenu ?
|
||||
<NotificationsMenu className={styles['notifications-menu']} />
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
navMenu ?
|
||||
<NavMenu className={styles['nav-menu']} />
|
||||
|
|
@ -87,6 +94,7 @@ NavBar.propTypes = {
|
|||
searchBar: PropTypes.bool,
|
||||
addonsButton: PropTypes.bool,
|
||||
fullscreenButton: PropTypes.bool,
|
||||
notificationsMenu: PropTypes.bool,
|
||||
navMenu: PropTypes.bool
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
const Button = require('stremio/common/Button');
|
||||
const Image = require('stremio/common/Image');
|
||||
const PlayIconCircleCentered = require('stremio/common/PlayIconCircleCentered');
|
||||
const styles = require('./styles');
|
||||
|
||||
const ICON_FOR_TYPE = Object.assign(Object.create(null), {
|
||||
'movie': 'ic_movies',
|
||||
'series': 'ic_series',
|
||||
'channel': 'ic_channels',
|
||||
'tv': 'ic_tv',
|
||||
'other': 'ic_movies'
|
||||
});
|
||||
|
||||
const Notification = ({ className, id, type, name, poster, thumbnail, season, episode, released, onClick }) => {
|
||||
const daysAgo = React.useMemo(() => {
|
||||
if (released instanceof Date) {
|
||||
return Math.floor(Math.abs((Date.now() - released) / (24 * 60 * 60 * 1000)));
|
||||
}
|
||||
}, [released]);
|
||||
return (
|
||||
<Button className={classnames(className, styles['notification-container'])} title={typeof name === 'string' && name.length > 0 ? name : id} data-id={id} onClick={onClick}>
|
||||
<div className={styles['logo-container']}>
|
||||
<div className={styles['logo-image-layer']}>
|
||||
<Image
|
||||
className={styles['logo-image']}
|
||||
src={poster}
|
||||
alt={' '}
|
||||
renderFallback={() => (
|
||||
<Icon
|
||||
className={styles['placeholder-icon']}
|
||||
icon={typeof ICON_FOR_TYPE[type] === 'string' ? ICON_FOR_TYPE[type] : ICON_FOR_TYPE['other']}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles['info-container']}>
|
||||
<div className={styles['episode-container']}>
|
||||
{episode !== null && !isNaN(episode) ? `E${episode} ` : null}
|
||||
{season !== null && !isNaN(season) ? `S${season} ` : null}
|
||||
</div>
|
||||
<div className={styles['name-container']}>
|
||||
{typeof name === 'string' && name.length > 0 ? name : id}
|
||||
</div>
|
||||
{
|
||||
daysAgo !== null && !isNaN(daysAgo) ?
|
||||
<div className={styles['released-container']}>
|
||||
{daysAgo === 0 ? 'today' : daysAgo + ' days ago'}
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
{
|
||||
typeof thumbnail === 'string' && thumbnail.length > 0 ?
|
||||
<div className={styles['poster-container']}>
|
||||
<div className={styles['poster-image-layer']}>
|
||||
<Image
|
||||
className={styles['poster-image']}
|
||||
src={thumbnail}
|
||||
alt={' '}
|
||||
renderFallback={() => (
|
||||
<Icon
|
||||
className={styles['placeholder-icon']}
|
||||
icon={typeof ICON_FOR_TYPE[type] === 'string' ? ICON_FOR_TYPE[type] : ICON_FOR_TYPE['other']}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles['play-icon-layer']}>
|
||||
<PlayIconCircleCentered className={styles['play-icon']} />
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
Notification.propTypes = {
|
||||
className: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
type: PropTypes.string,
|
||||
name: PropTypes.string,
|
||||
poster: PropTypes.string,
|
||||
thumbnail: PropTypes.string,
|
||||
season: PropTypes.number,
|
||||
episode: PropTypes.number,
|
||||
released: PropTypes.instanceOf(Date),
|
||||
onClick: PropTypes.func
|
||||
};
|
||||
|
||||
module.exports = Notification;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
const Notification = require('./Notification');
|
||||
|
||||
module.exports = Notification;
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
:import('~stremio/common/PlayIconCircleCentered/styles.less') {
|
||||
play-icon-circle-centered-background: background;
|
||||
play-icon-circle-centered-icon: icon;
|
||||
}
|
||||
|
||||
.notification-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 1rem;
|
||||
background-color: var(--color-surfacelighter);
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: var(--color-surfacelight);
|
||||
|
||||
.poster-container {
|
||||
.play-icon-layer {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.logo-container, .poster-container {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
height: 3.5rem;
|
||||
background-color: var(--color-backgroundlight);
|
||||
|
||||
.logo-image-layer, .poster-image-layer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: -3;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.logo-image, .poster-image {
|
||||
flex: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-position: center;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.placeholder-icon {
|
||||
flex: none;
|
||||
width: 80%;
|
||||
height: 50%;
|
||||
fill: var(--color-surfacelight20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
width: 3.5rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.info-container {
|
||||
flex: 1;
|
||||
align-self: stretch;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-content: flex-start;
|
||||
padding: 0 1rem;
|
||||
|
||||
&:first-child {
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.episode-container {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: 100%;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.name-container {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: 100%;
|
||||
max-height: 3.6em;
|
||||
}
|
||||
|
||||
.released-container {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: 100%;
|
||||
margin-top: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
color: var(--color-surfacedark);
|
||||
}
|
||||
}
|
||||
|
||||
.poster-container {
|
||||
width: 6rem;
|
||||
|
||||
.play-icon-layer {
|
||||
position: absolute;
|
||||
top: 20%;
|
||||
right: 0;
|
||||
bottom: 20%;
|
||||
left: 0;
|
||||
z-index: -2;
|
||||
display: none;
|
||||
overflow: visible;
|
||||
|
||||
.play-icon {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
filter: drop-shadow(0 0 0.5rem var(--color-backgroundlight));
|
||||
|
||||
.play-icon-circle-centered-background {
|
||||
fill: var(--color-surfacelighter);
|
||||
}
|
||||
|
||||
.play-icon-circle-centered-icon {
|
||||
fill: var(--color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: thin solid var(--color-surfacelight);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
const styles = require('./styles');
|
||||
|
||||
const NotificationPlaceholder = ({ className }) => {
|
||||
return (
|
||||
<div className={classnames(className, styles['notification-placeholder-container'])}>
|
||||
<div className={styles['logo-image-container']}>
|
||||
<div className={styles['logo-image']} />
|
||||
</div>
|
||||
<div className={styles['info-container']}>
|
||||
<div className={styles['name-container']} />
|
||||
<div className={styles['released-container']} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
NotificationPlaceholder.propTypes = {
|
||||
className: PropTypes.string
|
||||
}
|
||||
|
||||
module.exports = NotificationPlaceholder;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
const NotificationPlaceholder = require('./NotificationPlaceholder');
|
||||
|
||||
module.exports = NotificationPlaceholder;
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
.notification-placeholder-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
|
||||
.logo-image-container {
|
||||
flex: none;
|
||||
border-radius: 50%;
|
||||
|
||||
.logo-image {
|
||||
width: 3.5rem;
|
||||
height: 3.5rem;
|
||||
background-color: var(--color-placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
.info-container {
|
||||
flex: 1;
|
||||
padding: 0 1rem;
|
||||
|
||||
.name-container {
|
||||
width: 100%;
|
||||
height: 1.2rem;
|
||||
background: var(--color-placeholder);
|
||||
}
|
||||
|
||||
.released-container {
|
||||
width: 50%;
|
||||
height: 1.2rem;
|
||||
margin-top: 0.5rem;
|
||||
background: var(--color-placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: thin solid var(--color-surfacelight);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
const Notification = require('./Notification');
|
||||
const NotificationPlaceholder = require('./NotificationPlaceholder');
|
||||
const styles = require('./styles');
|
||||
|
||||
const NotificationsList = ({ className, metaItems }) => {
|
||||
return (
|
||||
<div className={classnames(className, styles['notifications-list-scroll-container'])}>
|
||||
{
|
||||
metaItems.map(({ req, content }, index) => {
|
||||
switch (content.type) {
|
||||
case 'Ready':
|
||||
return (
|
||||
content.content.length > 0 ?
|
||||
content.content.map((notification) => {
|
||||
//notifications videos are not available in useCatalogs, but in useNotifications hook
|
||||
notification.videos = notification.videos || [{
|
||||
title: 'Demo title',
|
||||
thumbnail: 'https://www.stremio.com/website/home-testimonials.jpg',
|
||||
season: 1,
|
||||
episode: 1,
|
||||
released: new Date()
|
||||
}];
|
||||
|
||||
return (
|
||||
<Notification
|
||||
{...notification}
|
||||
key={`${index}${req.base}${content.type}${notification.id}`}
|
||||
className={styles['notification']}
|
||||
name={notification.videos.length === 1 ? notification.videos[0].title : notification.videos.length + ' new videos for ' + notification.name}
|
||||
thumbnail={notification.videos.length === 1 ? notification.videos[0].thumbnail : null}
|
||||
season={notification.videos.length === 1 ? notification.videos[0].season : null}
|
||||
episode={notification.videos.length === 1 ? notification.videos[0].episode : null}
|
||||
released={notification.videos.length === 1 ? notification.videos[0].released : notification.videos[notification.videos.length - 1].released}
|
||||
|
||||
/>
|
||||
);
|
||||
})
|
||||
:
|
||||
<div className={styles['no-notifications-container']}>
|
||||
<Icon className={styles['icon']} icon={'ic_bell'} />
|
||||
<div className={styles['label']}>No new notifications</div>
|
||||
</div>
|
||||
);
|
||||
case 'Loading':
|
||||
return (
|
||||
<NotificationPlaceholder
|
||||
key={`${index}${req.base}${content.type}`}
|
||||
className={styles['notification']}
|
||||
/>
|
||||
);
|
||||
}
|
||||
})
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
NotificationsList.propTypes = {
|
||||
className: PropTypes.string,
|
||||
metaItems: PropTypes.arrayOf(PropTypes.object)
|
||||
};
|
||||
|
||||
module.exports = NotificationsList;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
const NotificationsList = require('./NotificationsList');
|
||||
|
||||
module.exports = NotificationsList;
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
.notifications-list-scroll-container {
|
||||
flex: 1;
|
||||
align-self: stretch;
|
||||
overflow-y: auto;
|
||||
background-color: var(--color-surfacelighter);
|
||||
|
||||
.notification {
|
||||
width: var(--item-size);
|
||||
}
|
||||
|
||||
.no-notifications-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: var(--item-size);
|
||||
height: 100%;
|
||||
padding: 1rem;
|
||||
|
||||
.icon {
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
margin-bottom: 2rem;
|
||||
fill: var(--color-surfacedark);
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
color: var(--color-surfacedark);
|
||||
}
|
||||
}
|
||||
|
||||
&:global(::-webkit-scrollbar-track) {
|
||||
background-color: var(--color-surfacelighter);
|
||||
}
|
||||
}
|
||||
48
src/common/NavBar/NotificationsMenu/NotificationsMenu.js
Normal file
48
src/common/NavBar/NotificationsMenu/NotificationsMenu.js
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
const Button = require('stremio/common/Button');
|
||||
const Popup = require('stremio/common/Popup');
|
||||
const NotificationsList = require('./NotificationsList');
|
||||
const useNotifications = require('./useNotifications');
|
||||
const useCatalogs = require('stremio/routes/Board/useCatalogs');
|
||||
const useBinaryState = require('stremio/common/useBinaryState');
|
||||
const styles = require('./styles');
|
||||
|
||||
const NotificationsMenu = ({ className, onClearButtonClicked }) => {
|
||||
const [menuOpen, openMenu, closeMenu, toggleMenu] = useBinaryState(false);
|
||||
//TODO use useNotifications hook instead of useCatalogs
|
||||
const metaItems = useCatalogs();
|
||||
|
||||
return (
|
||||
<Popup
|
||||
open={menuOpen}
|
||||
onCloseRequest={closeMenu}
|
||||
renderLabel={({ref, className: popupLabelClassName, children}) => (
|
||||
<Button ref={ref} className={classnames(className, popupLabelClassName, styles['notifications-menu-label-container'], { 'active': menuOpen })} tabIndex={-1} onClick={toggleMenu}>
|
||||
<Icon className={styles['icon']} icon={'ic_bell'} />
|
||||
{children}
|
||||
</Button>
|
||||
)}
|
||||
renderMenu={() => (
|
||||
<div className={styles['notifications-menu-container']}>
|
||||
<div className={styles['notifications-bar']}>
|
||||
<div className={styles['notifications-label']}>Notifications</div>
|
||||
<Button className={styles['button-container']} onClick={onClearButtonClicked}>
|
||||
<Icon className={styles['icon']} icon={'ic_drawer'} />
|
||||
</Button>
|
||||
</div>
|
||||
<NotificationsList className={styles['notifications-list']} metaItems={metaItems}/>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
NotificationsMenu.propTypes = {
|
||||
className: PropTypes.string,
|
||||
onClearButtonClicked: PropTypes.func
|
||||
};
|
||||
|
||||
module.exports = NotificationsMenu;
|
||||
3
src/common/NavBar/NotificationsMenu/index.js
Normal file
3
src/common/NavBar/NotificationsMenu/index.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
const NotificationsMenu = require('./NotificationsMenu');
|
||||
|
||||
module.exports = NotificationsMenu;
|
||||
68
src/common/NavBar/NotificationsMenu/styles.less
Normal file
68
src/common/NavBar/NotificationsMenu/styles.less
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
.notifications-menu-label-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-secondary);
|
||||
}
|
||||
|
||||
&:global(.active) {
|
||||
background-color: var(--color-background);
|
||||
}
|
||||
|
||||
.icon {
|
||||
flex: none;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
fill: var(--color-surfacelighter);
|
||||
}
|
||||
|
||||
.notifications-menu-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.notifications-bar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.5rem;
|
||||
border-bottom: thin solid var(--color-surfacelight);
|
||||
|
||||
background-color: var(--color-surfacelighter);
|
||||
|
||||
.notifications-label {
|
||||
padding-left: 0.5rem;
|
||||
color: var(--color-surfacedark);
|
||||
}
|
||||
|
||||
.button-container {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: var(--color-surfacelight);
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 1.2rem;
|
||||
fill: var(--color-surfacedark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.notifications-list {
|
||||
--item-size: 28rem;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: auto;
|
||||
height: 30rem;
|
||||
align-self: stretch;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/common/NavBar/NotificationsMenu/useNotifications.js
Normal file
26
src/common/NavBar/NotificationsMenu/useNotifications.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
const React = require('react');
|
||||
const { useServices } = require('stremio/services');
|
||||
|
||||
const useNotifications = () => {
|
||||
const [notifications, setNotifications] = React.useState([]);
|
||||
const { core } = useServices();
|
||||
React.useEffect(() => {
|
||||
const onNewState = () => {
|
||||
const state = core.getState();
|
||||
setNotifications(state.notifications.groups);
|
||||
};
|
||||
core.on('NewModel', onNewState);
|
||||
core.dispatch({
|
||||
action: 'Load',
|
||||
args: {
|
||||
load: 'Notifications'
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
core.off('NewModel', onNewState);
|
||||
};
|
||||
}, []);
|
||||
return notifications;
|
||||
};
|
||||
|
||||
module.exports = useNotifications;
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.addons-button, .fullscreen-button, .nav-menu {
|
||||
.addons-button, .fullscreen-button, .notifications-menu, .nav-menu {
|
||||
flex: none;
|
||||
width: var(--nav-bar-size);
|
||||
height: var(--nav-bar-size);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ const Settings = () => {
|
|||
backButton={true}
|
||||
addonsButton={true}
|
||||
fullscreenButton={true}
|
||||
notificationsMenu={true}
|
||||
navMenu={true} />
|
||||
<div className={styles['settings-container']}>
|
||||
<SectionsSelector className={styles['side-menu']} sections={sections} selectedSectionId={selectedSectionId} onSelectedSection={changeSection} />
|
||||
|
|
|
|||
18
storybook/stories/Notification/MultipleVideosNotification.js
Normal file
18
storybook/stories/Notification/MultipleVideosNotification.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const React = require('react');
|
||||
const { storiesOf } = require('@storybook/react');
|
||||
const { action } = require('@storybook/addon-actions');
|
||||
const Notification = require('stremio/common/NavBar/NotificationsMenu/NotificationsList/Notification');
|
||||
const styles = require('./styles');
|
||||
|
||||
storiesOf('Notification', module).add('MultipleVideos', () => (
|
||||
<Notification
|
||||
className={styles['multiple-videos-notification-container']}
|
||||
id={'notification-id'}
|
||||
type={'series'}
|
||||
name={'Demo name'}
|
||||
poster={'/images/intro_background.jpg'}
|
||||
thumbnail={null}
|
||||
released={new Date()}
|
||||
onClick={action('Demo item clicked')}
|
||||
/>
|
||||
));
|
||||
20
storybook/stories/Notification/SingleVideoNotification.js
Normal file
20
storybook/stories/Notification/SingleVideoNotification.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
const React = require('react');
|
||||
const { storiesOf } = require('@storybook/react');
|
||||
const { action } = require('@storybook/addon-actions');
|
||||
const Notification = require('stremio/common/NavBar/NotificationsMenu/NotificationsList/Notification');
|
||||
const styles = require('./styles');
|
||||
|
||||
storiesOf('Notification', module).add('SingleVideo', () => (
|
||||
<Notification
|
||||
className={styles['single-video-notification-container']}
|
||||
id={'notification-id'}
|
||||
type={'series'}
|
||||
name={'Demo name'}
|
||||
poster={'/images/intro_background.jpg'}
|
||||
thumbnail={'/images/intro_background.jpg'}
|
||||
season={1}
|
||||
episode={1}
|
||||
released={new Date()}
|
||||
onClick={action('Demo item clicked')}
|
||||
/>
|
||||
));
|
||||
2
storybook/stories/Notification/index.js
Normal file
2
storybook/stories/Notification/index.js
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
require('./SingleVideoNotification');
|
||||
require('./MultipleVideosNotification');
|
||||
3
storybook/stories/Notification/styles.less
Normal file
3
storybook/stories/Notification/styles.less
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.single-video-notification-container, .multiple-videos-notification-container {
|
||||
width: 28rem;
|
||||
}
|
||||
|
|
@ -2,3 +2,4 @@ require('./Addon');
|
|||
require('./MetaItem');
|
||||
require('./ColorPicker');
|
||||
require('./SharePrompt');
|
||||
require('./Notification');
|
||||
|
|
|
|||
Loading…
Reference in a new issue