mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-11 21:27:05 +00:00
refactor(MetaPreview): usage of ratings
This commit is contained in:
parent
beb873e34e
commit
38d5290d91
7 changed files with 99 additions and 31 deletions
|
|
@ -8,9 +8,9 @@ const { Button } = require('stremio/components');
|
|||
const styles = require('./styles');
|
||||
const { Tooltip } = require('stremio/common/Tooltips');
|
||||
|
||||
const ActionButton = ({ className, icon, label, tooltip, ...props }) => {
|
||||
const ActionButton = ({ className, icon, label, tooltip, showLabel = true, ...props }) => {
|
||||
return (
|
||||
<Button title={tooltip ? '' : label} {...props} className={classnames(className, styles['action-button-container'], { 'wide': typeof label === 'string' && !tooltip })}>
|
||||
<Button title={tooltip ? '' : label} {...props} className={classnames(className, styles['action-button-container'], { 'wide': typeof label === 'string' && !tooltip && showLabel })}>
|
||||
{
|
||||
tooltip === true ?
|
||||
<Tooltip label={label} position={'top'} />
|
||||
|
|
@ -26,7 +26,7 @@ const ActionButton = ({ className, icon, label, tooltip, ...props }) => {
|
|||
null
|
||||
}
|
||||
{
|
||||
!tooltip && typeof label === 'string' && label.length > 0 ?
|
||||
!tooltip && typeof label === 'string' && label.length > 0 && showLabel ?
|
||||
<div className={styles['label-container']}>
|
||||
<div className={styles['label']}>{label}</div>
|
||||
</div>
|
||||
|
|
@ -41,7 +41,8 @@ ActionButton.propTypes = {
|
|||
className: PropTypes.string,
|
||||
icon: PropTypes.string,
|
||||
label: PropTypes.string,
|
||||
tooltip: PropTypes.bool
|
||||
tooltip: PropTypes.bool,
|
||||
showLabel: PropTypes.bool
|
||||
};
|
||||
|
||||
module.exports = ActionButton;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,40 @@
|
|||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: var(--primary-foreground-color);
|
||||
opacity: 0.9;
|
||||
|
||||
.icon {
|
||||
color: var(--primary-background-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.rating-button {
|
||||
&.active {
|
||||
background-color: var(--primary-accent-color);
|
||||
|
||||
.icon {
|
||||
color: var(--primary-foreground-color);
|
||||
}
|
||||
|
||||
.label-container {
|
||||
display: flex;
|
||||
|
||||
.label {
|
||||
color: var(--primary-foreground-color);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.active) {
|
||||
.label-container {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media @phone-landscape {
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ const ALLOWED_LINK_REDIRECTS = [
|
|||
routesRegexp.metadetails.regexp
|
||||
];
|
||||
|
||||
const MetaPreview = React.forwardRef(({ className, compact, name, logo, background, runtime, releaseInfo, released, description, deepLinks, links, trailerStreams, inLibrary, toggleInLibrary, metaDetails }, ref) => {
|
||||
const MetaPreview = React.forwardRef(({ className, compact, name, logo, background, runtime, releaseInfo, released, description, deepLinks, links, trailerStreams, inLibrary, toggleInLibrary, metaId, like }, ref) => {
|
||||
const { t } = useTranslation();
|
||||
const { onLiked, onLoved } = useRating(metaDetails);
|
||||
const { onLiked, onLoved, liked, loved } = useRating(metaId, like);
|
||||
const [shareModalOpen, openShareModal, closeShareModal] = useBinaryState(false);
|
||||
const linksGroups = React.useMemo(() => {
|
||||
return Array.isArray(links) ?
|
||||
|
|
@ -263,8 +263,12 @@ const MetaPreview = React.forwardRef(({ className, compact, name, logo, backgrou
|
|||
{
|
||||
!compact ?
|
||||
<ActionButton
|
||||
className={styles['action-button']}
|
||||
icon={'volume-medium'}
|
||||
className={classnames(styles['action-button'], styles['rating-button'], {
|
||||
[styles['active']]: liked
|
||||
})}
|
||||
icon={'thumbs-up'}
|
||||
label={t('LIKE')}
|
||||
showLabel={liked}
|
||||
tabIndex={compact ? -1 : 0}
|
||||
onClick={onLiked}
|
||||
tooltip={compact}
|
||||
|
|
@ -275,8 +279,12 @@ const MetaPreview = React.forwardRef(({ className, compact, name, logo, backgrou
|
|||
{
|
||||
!compact ?
|
||||
<ActionButton
|
||||
className={styles['action-button']}
|
||||
icon={'volume-high'}
|
||||
className={classnames(styles['action-button'], styles['rating-button'], {
|
||||
[styles['active']]: loved
|
||||
})}
|
||||
icon={'heart'}
|
||||
label={t('LOVE')}
|
||||
showLabel={loved}
|
||||
tabIndex={compact ? -1 : 0}
|
||||
onClick={onLoved}
|
||||
tooltip={compact}
|
||||
|
|
@ -314,7 +322,8 @@ MetaPreview.propTypes = {
|
|||
trailerStreams: PropTypes.array,
|
||||
inLibrary: PropTypes.bool,
|
||||
toggleInLibrary: PropTypes.func,
|
||||
metaDetails: PropTypes.object
|
||||
metaId: PropTypes.string,
|
||||
like: PropTypes.object,
|
||||
};
|
||||
|
||||
module.exports = MetaPreview;
|
||||
|
|
|
|||
|
|
@ -207,6 +207,26 @@
|
|||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.rating-button {
|
||||
&.active {
|
||||
width: auto;
|
||||
padding: 0 2rem;
|
||||
border-radius: 4rem;
|
||||
background-color: var(--primary-accent-color);
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: var(--primary-accent-color);
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.active) {
|
||||
&:hover, &:focus {
|
||||
background-color: var(--overlay-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,15 @@
|
|||
import { useMemo, useCallback } from 'react';
|
||||
import { useServices } from 'stremio/services';
|
||||
|
||||
const useRating = (metaDetails: MetaDetails) => {
|
||||
if (!metaDetails) {
|
||||
return {
|
||||
onLiked: () => {},
|
||||
onLoved: () => {},
|
||||
};
|
||||
}
|
||||
type Like = {
|
||||
content: 'liked' | 'loved' | null;
|
||||
type: 'Ready' | 'Loading' | 'Error';
|
||||
};
|
||||
|
||||
const useRating = (metaId?: string, like?: Like) => {
|
||||
const { core } = useServices();
|
||||
|
||||
const like = useMemo(() => {
|
||||
return metaDetails.like?.type === 'Ready' ? metaDetails.like.content : null;
|
||||
}, [metaDetails.like]);
|
||||
|
||||
const setRating = useCallback((status: LoadableError | null) => {
|
||||
const metaId = metaDetails.metaItem?.content?.content?.id;
|
||||
if (!metaId) return;
|
||||
|
||||
const setRating = useCallback((status: 'liked' | 'loved' | null) => {
|
||||
core.transport.dispatch({
|
||||
action: 'MetaDetails',
|
||||
args: {
|
||||
|
|
@ -28,20 +20,29 @@ const useRating = (metaDetails: MetaDetails) => {
|
|||
},
|
||||
},
|
||||
});
|
||||
}, [metaDetails.metaItem?.content?.content?.id]);
|
||||
}, [core]);
|
||||
|
||||
const liked = useMemo(() => {
|
||||
return like?.content === 'liked';
|
||||
}, [like]);
|
||||
|
||||
const loved = useMemo(() => {
|
||||
return like?.content === 'loved';
|
||||
}, [like]);
|
||||
|
||||
const onLiked = useCallback(() => {
|
||||
setRating(like === 'liked' ? null : 'liked');
|
||||
setRating(like?.content === 'liked' ? null : 'liked');
|
||||
}, [like, setRating]);
|
||||
|
||||
const onLoved = useCallback(() => {
|
||||
setRating(like === 'loved' ? null : 'loved');
|
||||
setRating(like?.content === 'loved' ? null : 'loved');
|
||||
}, [like, setRating]);
|
||||
|
||||
return {
|
||||
onLiked,
|
||||
onLoved,
|
||||
like,
|
||||
liked,
|
||||
loved,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -191,6 +191,8 @@ const Discover = ({ urlParams, queryParams }) => {
|
|||
trailerStreams={selectedMetaItem.trailerStreams}
|
||||
inLibrary={selectedMetaItem.inLibrary}
|
||||
toggleInLibrary={selectedMetaItem.inLibrary ? removeFromLibrary : addToLibrary}
|
||||
metaId={selectedMetaItem.id}
|
||||
like={selectedMetaItem.like}
|
||||
/>
|
||||
:
|
||||
discover.catalog !== null && discover.catalog.content.type === 'Loading' ?
|
||||
|
|
|
|||
|
|
@ -166,7 +166,8 @@ const MetaDetails = ({ urlParams, queryParams }) => {
|
|||
trailerStreams={metaDetails.metaItem.content.content.trailerStreams}
|
||||
inLibrary={metaDetails.metaItem.content.content.inLibrary}
|
||||
toggleInLibrary={metaDetails.metaItem.content.content.inLibrary ? removeFromLibrary : addToLibrary}
|
||||
metaDetails={metaDetails}
|
||||
metaId={metaDetails.metaItem.content.content.id}
|
||||
like={metaDetails.like}
|
||||
/>
|
||||
</React.Fragment>
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue