mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-20 10:42:12 +00:00
simple meta item implemented
This commit is contained in:
parent
15ca1fb614
commit
d1c15fcb0d
4 changed files with 47 additions and 312 deletions
|
|
@ -44,6 +44,8 @@
|
|||
|
||||
:root {
|
||||
--scroll-bar-width: 8px;
|
||||
--landscape-shape-ratio: 0.5625;
|
||||
--poster-shape-ratio: 1.464;
|
||||
}
|
||||
|
||||
:global {
|
||||
|
|
|
|||
|
|
@ -1,173 +1,28 @@
|
|||
import React from 'react';
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Icon, { dataUrl as iconDataUrl } from 'stremio-icons/dom';
|
||||
import colors from 'stremio-colors';
|
||||
import { RELATIVE_POSTER_SIZE } from './constants';
|
||||
import classnames from 'classnames';
|
||||
import styles from './styles';
|
||||
|
||||
const getShapeSize = (posterShape, progress) => {
|
||||
switch (posterShape) {
|
||||
case 'poster':
|
||||
return {
|
||||
width: RELATIVE_POSTER_SIZE
|
||||
};
|
||||
case 'landscape':
|
||||
return {
|
||||
width: RELATIVE_POSTER_SIZE / 0.5625
|
||||
};
|
||||
default:
|
||||
if (progress) {
|
||||
return {
|
||||
width: RELATIVE_POSTER_SIZE * 1.464
|
||||
};
|
||||
}
|
||||
return {
|
||||
width: RELATIVE_POSTER_SIZE
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const getPlaceholderIcon = (type) => {
|
||||
switch (type) {
|
||||
case 'tv':
|
||||
return 'ic_tv';
|
||||
case 'series':
|
||||
return 'ic_series';
|
||||
case 'channel':
|
||||
return 'ic_channels';
|
||||
default:
|
||||
return 'ic_movies';
|
||||
}
|
||||
}
|
||||
|
||||
const renderProgress = (progress) => {
|
||||
if (progress <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles['progress-container']}>
|
||||
<div style={{ width: progress + '%' }} className={styles['progress']} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const renderEpisode = (episode) => {
|
||||
if (episode.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles['episode']}>{episode}</div>
|
||||
);
|
||||
}
|
||||
|
||||
const renderTitle = (title) => {
|
||||
if (title.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles['title']}>{title}</div>
|
||||
);
|
||||
}
|
||||
|
||||
const renderReleaseInfo = (releaseInfo) => {
|
||||
if (releaseInfo.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles['year']}>{releaseInfo}</div>
|
||||
);
|
||||
}
|
||||
|
||||
const renderPopupIcon = (onItemClicked, popup) => {
|
||||
if (!popup) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div onClick={onItemClicked} className={styles['popup-icon-container']}>
|
||||
<Icon className={styles['popup-icon']} icon={'ic_more'} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const getClassName = (progress, posterShape, title, releaseInfo, episode) => {
|
||||
if ((progress > 0) && (title.length > 0 || releaseInfo.length > 0 || episode.length > 0)) {
|
||||
if (posterShape === 'landscape') return 'progress-info-landscape-shape';
|
||||
if (posterShape === 'square') return 'progress-info-square-shape';
|
||||
return 'progress-info-poster-shape';
|
||||
}
|
||||
if ((progress > 0) && (title.length === 0 && releaseInfo.length === 0 && episode.length === 0)) {
|
||||
if (posterShape === 'landscape') return 'progress-landscape-shape';
|
||||
if (posterShape === 'square') return 'progress-square-shape';
|
||||
return 'progress-poster-shape';
|
||||
}
|
||||
if (!progress && (title.length > 0 || releaseInfo.length > 0 || episode.length > 0)) {
|
||||
if (posterShape === 'landscape') return 'info-landscape-shape';
|
||||
if (posterShape === 'square') return 'info-square-shape';
|
||||
return 'info-poster-shape';
|
||||
}
|
||||
if (!progress && (title.length === 0 && releaseInfo.length === 0 && episode.length === 0)) {
|
||||
if (posterShape === 'landscape') return 'landscape-shape';
|
||||
if (posterShape === 'square') return 'square-shape';
|
||||
return 'poster-shape';
|
||||
}
|
||||
return 'meta-item';
|
||||
}
|
||||
|
||||
const MetaItem = (props) => {
|
||||
const posterSize = getShapeSize(props.posterShape, props.progress);
|
||||
const contentContainerStyle = {
|
||||
width: posterSize.width
|
||||
};
|
||||
const placeholderIcon = getPlaceholderIcon(props.type);
|
||||
const placeholderIconUrl = iconDataUrl({ icon: placeholderIcon, fill: colors.accent, width: Math.round(RELATIVE_POSTER_SIZE / 2.2), height: Math.round(RELATIVE_POSTER_SIZE / 2.2) });
|
||||
const imageStyle = {
|
||||
backgroundImage: `url(${props.poster}), url('${placeholderIconUrl}')`
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={contentContainerStyle} className={styles[getClassName(props.progress, props.posterShape, props.title, props.releaseInfo, props.episode)]}>
|
||||
<div style={imageStyle} className={styles['poster']}>
|
||||
<div onClick={props.play} style={props.progress ? { visibility: 'visible' } : null} className={styles['play-container']}>
|
||||
<Icon className={styles['play']} icon={'ic_play'} />
|
||||
</div>
|
||||
class MetaItem extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className={classnames(styles['meta-item-container'], styles[`relative-size-${this.props.relativeSize}`], styles[`poster-shape-${this.props.posterShape}`], this.props.className)}>
|
||||
<div style={{ backgroundImage: `url('${this.props.poster}')` }} className={styles['poster-image']} />
|
||||
</div>
|
||||
{renderProgress(props.progress)}
|
||||
<div className={styles['info']}>
|
||||
{renderEpisode(props.episode)}
|
||||
{renderTitle(props.title)}
|
||||
{renderReleaseInfo(props.releaseInfo)}
|
||||
</div>
|
||||
{renderPopupIcon(props.onItemClicked, props.popup)}
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
MetaItem.propTypes = {
|
||||
type: PropTypes.oneOf(['movie', 'series', 'channel', 'tv', 'other']).isRequired,
|
||||
poster: PropTypes.string.isRequired,
|
||||
className: PropTypes.string,
|
||||
relativeSize: PropTypes.oneOf(['auto', 'height']).isRequired,
|
||||
posterShape: PropTypes.oneOf(['poster', 'landscape', 'square']).isRequired,
|
||||
progress: PropTypes.number.isRequired,
|
||||
episode: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
releaseInfo: PropTypes.string.isRequired,
|
||||
popup: PropTypes.bool.isRequired,
|
||||
play: PropTypes.func,
|
||||
onItemClicked: PropTypes.func
|
||||
poster: PropTypes.string.isRequired,
|
||||
};
|
||||
MetaItem.defaultProps = {
|
||||
type: 'other',
|
||||
relativeSize: 'auto',
|
||||
posterShape: 'square',
|
||||
poster: '',
|
||||
posterShape: 'poster',
|
||||
progress: 0,
|
||||
episode: '',
|
||||
title: '',
|
||||
releaseInfo: '',
|
||||
popup: false
|
||||
};
|
||||
|
||||
export default MetaItem;
|
||||
export default MetaItem;
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"RELATIVE_POSTER_SIZE": 138
|
||||
}
|
||||
|
|
@ -1,153 +1,34 @@
|
|||
.meta-item, .progress-poster-shape, .progress-landscape-shape, .progress-square-shape, .progress-info-poster-shape, .progress-info-landscape-shape, .progress-info-square-shape, .poster-shape, .landscape-shape, .square-shape, .info-poster-shape, .info-landscape-shape, .info-square-shape {
|
||||
display: grid;
|
||||
color: var(--color-surfacelighter);
|
||||
.poster {
|
||||
grid-area: poster;
|
||||
display: flex;
|
||||
background-position: center;
|
||||
background-size: cover, auto;
|
||||
background-repeat: no-repeat;
|
||||
background-color: var(--color-backgrounddark);
|
||||
.play-container {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
visibility: hidden;
|
||||
border-radius: 50%;
|
||||
background-color: var(--color-surfacelighter);
|
||||
.play {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
margin: auto;
|
||||
margin-left: 26px;
|
||||
fill: var(--color-primary);
|
||||
.meta-item-container {
|
||||
margin: 10px;
|
||||
display: inline-block;
|
||||
|
||||
&.poster-shape-square {
|
||||
.poster-image {
|
||||
width: var(--poster-relative-size);
|
||||
height: var(--poster-relative-size);
|
||||
}
|
||||
}
|
||||
|
||||
&.poster-shape-landscape {
|
||||
.poster-image {
|
||||
width: calc(var(--poster-relative-size) / var(--landscape-shape-ratio));
|
||||
height: var(--poster-relative-size);
|
||||
}
|
||||
}
|
||||
|
||||
&.poster-shape-poster {
|
||||
&.relative-size-auto {
|
||||
.poster-image {
|
||||
width: var(--poster-relative-size);
|
||||
height: calc(var(--poster-relative-size) * var(--poster-shape-ratio));
|
||||
}
|
||||
}
|
||||
|
||||
&.relative-size-height {
|
||||
.poster-image {
|
||||
width: calc(var(--poster-relative-size) / var(--poster-shape-ratio));
|
||||
height: var(--poster-relative-size);
|
||||
}
|
||||
}
|
||||
}
|
||||
.progress-container {
|
||||
grid-area: progress;
|
||||
background-color: var(--color-surface);
|
||||
.progress {
|
||||
height: 4px;
|
||||
background-color: var(--color-primarylight);
|
||||
}
|
||||
}
|
||||
.info {
|
||||
grid-area: info;
|
||||
.title, .year, .episode {
|
||||
grid-area: text;
|
||||
color: var(--color-surfacelighter60);
|
||||
}
|
||||
:first-child {
|
||||
color: var(--color-surfacelighter);
|
||||
}
|
||||
}
|
||||
.popup-icon-container {
|
||||
grid-area: popupIcon;
|
||||
cursor: pointer;
|
||||
fill: var(--color-surfacelighter);
|
||||
.popup-icon {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
color: var(--color-backgrounddarker);
|
||||
background-color: var(--color-surfacelighter);
|
||||
outline: 2px solid var(--color-surfacelighter);
|
||||
.play-container {
|
||||
cursor: pointer;
|
||||
visibility: visible;
|
||||
}
|
||||
.info {
|
||||
.title, .year {
|
||||
color: var(--color-backgrounddarker60);
|
||||
}
|
||||
:first-child {
|
||||
color: var(--color-backgrounddarker);
|
||||
}
|
||||
}
|
||||
.popup-icon {
|
||||
fill: var(--color-backgrounddarker40);
|
||||
}
|
||||
}
|
||||
}
|
||||
.progress-poster-shape, .progress-landscape-shape, .progress-square-shape {
|
||||
grid-template-areas:
|
||||
"poster poster"
|
||||
"progress progress"
|
||||
". popupIcon";
|
||||
}
|
||||
.progress-poster-shape {
|
||||
grid-template-columns: 128px 10px;
|
||||
grid-template-rows: 202.03px 4px;
|
||||
}
|
||||
.progress-landscape-shape {
|
||||
grid-template-columns: 235.33px 10px;
|
||||
grid-template-rows: 202.03px 4px;
|
||||
}
|
||||
.progress-square-shape {
|
||||
grid-template-columns: 192.33px 10px;
|
||||
grid-template-rows: 202.03px 4px;
|
||||
}
|
||||
.progress-info-poster-shape, .progress-info-landscape-shape, .progress-info-square-shape {
|
||||
grid-template-areas:
|
||||
"poster poster"
|
||||
"progress progress"
|
||||
". ."
|
||||
"info popupIcon";
|
||||
}
|
||||
.progress-info-poster-shape {
|
||||
grid-template-columns: 128px 10px;
|
||||
grid-template-rows: 202.03px 4px 6px 77.97px;
|
||||
}
|
||||
.progress-info-landscape-shape {
|
||||
grid-template-columns: 235.33px 10px;
|
||||
grid-template-rows: 202.03px 4px 6px 77.97px;
|
||||
}
|
||||
.progress-info-square-shape {
|
||||
grid-template-columns: 192.33px 10px;
|
||||
grid-template-rows: 202.03px 4px 6px 77.97px;
|
||||
}
|
||||
.poster-shape, .landscape-shape, .square-shape {
|
||||
grid-template-areas:
|
||||
"poster poster"
|
||||
". popupIcon";
|
||||
}
|
||||
.poster-shape {
|
||||
grid-template-columns: 128px 10px;
|
||||
grid-template-rows: 202.03px;
|
||||
}
|
||||
.landscape-shape {
|
||||
grid-template-columns: 235.33px 10px;
|
||||
grid-template-rows: 138px;
|
||||
}
|
||||
.square-shape {
|
||||
grid-template-columns: 128px 10px;
|
||||
grid-template-rows: 138px;
|
||||
}
|
||||
.info-poster-shape, .info-landscape-shape, .info-square-shape {
|
||||
grid-template-areas:
|
||||
"poster poster"
|
||||
". ."
|
||||
"info popupIcon";
|
||||
}
|
||||
.info-poster-shape {
|
||||
grid-template-columns: 128px 10px;
|
||||
grid-template-rows: 202.03px 6px 81.97px;
|
||||
}
|
||||
.info-landscape-shape {
|
||||
grid-template-columns: 235.33px 10px;
|
||||
grid-template-rows: 138px 6px 64.97px;
|
||||
}
|
||||
.info-square-shape {
|
||||
grid-template-columns: 128px 10px;
|
||||
grid-template-rows: 138px 6px 64.97px;
|
||||
}
|
||||
.meta-item {
|
||||
grid-template-columns: 138px;
|
||||
grid-template-rows: 202.03px;
|
||||
grid-template-areas:
|
||||
"poster";
|
||||
}
|
||||
Loading…
Reference in a new issue