mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-29 05:38:48 +00:00
Notification component implemented
This commit is contained in:
parent
ab83a15d15
commit
4f9f9fd928
3 changed files with 237 additions and 0 deletions
|
|
@ -0,0 +1,96 @@
|
|||
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 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, logo, poster, season, episode, released, posterThumbnail, onClick }) => {
|
||||
const [aLogo, setALogo] = React.useState(logo);
|
||||
|
||||
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-image-container']}>
|
||||
{
|
||||
typeof aLogo === 'string' && aLogo.length > 0 ?
|
||||
<div className={styles['logo-image-layer']}>
|
||||
<img className={styles['logo-image']} src={logo} alt={' '} onError={() => { setALogo('') }} />
|
||||
</div>
|
||||
:
|
||||
<div className={styles['placeholder-icon-layer']}>
|
||||
<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>
|
||||
{
|
||||
released instanceof Date && !isNaN(released.getTime()) ?
|
||||
<div className={styles['released-container']}>
|
||||
{Math.floor(Math.abs((Date.now() - released) / (24 * 60 * 60 * 1000))) + ' days ago'}
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
{
|
||||
posterThumbnail ?
|
||||
<div className={styles['poster-image-container']}>
|
||||
<div className={styles['placeholder-icon-layer']}>
|
||||
<Icon
|
||||
className={styles['placeholder-icon']}
|
||||
icon={typeof ICON_FOR_TYPE[type] === 'string' ? ICON_FOR_TYPE[type] : ICON_FOR_TYPE['other']}
|
||||
/>
|
||||
</div>
|
||||
{
|
||||
typeof poster === 'string' && poster.length > 0 ?
|
||||
<div className={styles['poster-image-layer']}>
|
||||
<img className={styles['poster-image']} src={poster} alt={' '} />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
<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,
|
||||
logo: PropTypes.string,
|
||||
poster: PropTypes.string,
|
||||
season: PropTypes.number,
|
||||
episode: PropTypes.number,
|
||||
released: PropTypes.instanceOf(Date),
|
||||
posterThumbnail: PropTypes.bool,
|
||||
onClick: PropTypes.func
|
||||
};
|
||||
|
||||
module.exports = Notification;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
const Notification = require('./Notification');
|
||||
|
||||
module.exports = Notification;
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
: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;
|
||||
border-bottom: thin solid var(--color-surfacelight);
|
||||
background-color: var(--color-surfacelighter);
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: var(--color-surfacelight);
|
||||
|
||||
.poster-image-container {
|
||||
.play-icon-layer {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.logo-image-container, .poster-image-container {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
height: 3.5rem;
|
||||
background-color: var(--color-backgroundlight);
|
||||
|
||||
.placeholder-icon-layer {
|
||||
position: absolute;
|
||||
top: 25%;
|
||||
right: 10%;
|
||||
bottom: 25%;
|
||||
left: 10%;
|
||||
z-index: 0;
|
||||
|
||||
.placeholder-icon {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: var(--color-surfacelight20);
|
||||
}
|
||||
}
|
||||
|
||||
.logo-image-layer, .poster-image-layer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
|
||||
.logo-image, .poster-image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.logo-image-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: 4.7em;
|
||||
}
|
||||
|
||||
.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-image-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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue