mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-11 21:27:05 +00:00
feat: icons group component
This commit is contained in:
parent
852f478f1e
commit
3b2d1f365c
7 changed files with 78 additions and 52 deletions
|
|
@ -6,7 +6,7 @@ const classnames = require('classnames');
|
|||
const MetaItem = require('stremio/components/MetaItem');
|
||||
const { t } = require('i18next');
|
||||
|
||||
const DiscItem = ({ id, watched, selected, toggleWatched, select, ...props }) => {
|
||||
const DiscItem = ({ id, watched, selected, toggleWatched, ...props }) => {
|
||||
|
||||
const options = React.useMemo(() => {
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
@width-mobile: 3rem;
|
||||
|
||||
|
||||
.ratings-container {
|
||||
.group-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
|
@ -17,6 +17,8 @@
|
|||
border-radius: 2rem;
|
||||
height: @height;
|
||||
width: fit-content;
|
||||
margin-bottom: 1rem;
|
||||
margin-right: 1rem;
|
||||
|
||||
.icon-container {
|
||||
display: flex;
|
||||
|
|
@ -45,7 +47,7 @@
|
|||
}
|
||||
|
||||
@media @phone-landscape {
|
||||
.ratings-container {
|
||||
.group-container {
|
||||
height: @height-mobile;
|
||||
|
||||
.icon-container {
|
||||
36
src/components/IconsGroup/IconsGroup.tsx
Normal file
36
src/components/IconsGroup/IconsGroup.tsx
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (C) 2017-2023 Smart code 203358507
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import Icon from '@stremio/stremio-icons/react';
|
||||
import styles from './IconsGroup.less';
|
||||
|
||||
type GroupItem = {
|
||||
icon: string;
|
||||
filled?: string;
|
||||
disabled?: boolean;
|
||||
className?: string;
|
||||
onClick?: () => void;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
items: GroupItem[];
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const IconsGroup = ({ items, className }: Props) => {
|
||||
return (
|
||||
<div className={classNames(styles['group-container'], className)}>
|
||||
{items.map((item, index) => (
|
||||
<div key={index}
|
||||
className={classNames(styles['icon-container'], item.className, { [styles['disabled']]: item.disabled })}
|
||||
onClick={item.onClick}
|
||||
>
|
||||
<Icon name={item.icon} className={styles['icon']} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default IconsGroup;
|
||||
6
src/components/IconsGroup/index.ts
Normal file
6
src/components/IconsGroup/index.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// Copyright (C) 2017-2023 Smart code 203358507
|
||||
|
||||
import IconsGroup from './IconsGroup';
|
||||
|
||||
export { IconsGroup };
|
||||
|
||||
|
|
@ -8,6 +8,7 @@ const { useTranslation } = require('react-i18next');
|
|||
const { default: Icon } = require('@stremio/stremio-icons/react');
|
||||
const { default: Button } = require('stremio/components/Button');
|
||||
const { default: Image } = require('stremio/components/Image');
|
||||
const { IconsGroup } = require('stremio/components/IconsGroup');
|
||||
const ModalDialog = require('stremio/components/ModalDialog');
|
||||
const SharePrompt = require('stremio/components/SharePrompt');
|
||||
const CONSTANTS = require('stremio/common/CONSTANTS');
|
||||
|
|
@ -98,6 +99,16 @@ const MetaPreview = React.forwardRef(({ className, compact, name, logo, backgrou
|
|||
const renderLogoFallback = React.useCallback(() => (
|
||||
<div className={styles['logo-placeholder']}>{name}</div>
|
||||
), [name]);
|
||||
const libAndWatchedGroup = React.useMemo(() => [
|
||||
{
|
||||
icon: inLibrary ? 'remove-from-library' : 'add-to-library',
|
||||
onClick: typeof toggleInLibrary === 'function' ? toggleInLibrary : null,
|
||||
},
|
||||
{
|
||||
icon: watched ? 'eye-off' : 'eye',
|
||||
onClick: typeof toggleWatched === 'function' ? toggleWatched : undefined,
|
||||
},
|
||||
], [inLibrary, watched, toggleInLibrary, toggleWatched]);
|
||||
return (
|
||||
<div className={classnames(className, styles['meta-preview-container'], { [styles['compact']]: compact })} ref={ref}>
|
||||
{
|
||||
|
|
@ -209,30 +220,9 @@ const MetaPreview = React.forwardRef(({ className, compact, name, logo, backgrou
|
|||
null
|
||||
}
|
||||
{
|
||||
typeof toggleInLibrary === 'function' ?
|
||||
<ActionButton
|
||||
className={styles['action-button']}
|
||||
icon={inLibrary ? 'remove-from-library' : 'add-to-library'}
|
||||
label={inLibrary ? t('REMOVE_FROM_LIB') : t('ADD_TO_LIB')}
|
||||
tooltip={compact}
|
||||
tabIndex={compact ? -1 : 0}
|
||||
onClick={toggleInLibrary}
|
||||
/>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
typeof toggleWatched === 'function' ?
|
||||
<ActionButton
|
||||
className={styles['action-button']}
|
||||
icon={watched ? 'eye-off' : 'eye'}
|
||||
label={watched ? t('CTX_MARK_UNWATCHED') : t('CTX_MARK_WATCHED')}
|
||||
tooltip={compact}
|
||||
tabIndex={compact ? -1 : 0}
|
||||
onClick={toggleWatched}
|
||||
/>
|
||||
:
|
||||
null
|
||||
typeof toggleInLibrary === 'function' && typeof toggleWatched === 'function'
|
||||
? <IconsGroup items={libAndWatchedGroup} />
|
||||
: null
|
||||
}
|
||||
{
|
||||
typeof showHref === 'string' && compact ?
|
||||
|
|
@ -247,13 +237,9 @@ const MetaPreview = React.forwardRef(({ className, compact, name, logo, backgrou
|
|||
null
|
||||
}
|
||||
{
|
||||
!compact && ratingInfo !== null ?
|
||||
<Ratings
|
||||
ratingInfo={ratingInfo}
|
||||
className={styles['ratings']}
|
||||
/>
|
||||
:
|
||||
null
|
||||
!compact && ratingInfo !== null
|
||||
? <Ratings ratingInfo={ratingInfo} />
|
||||
: null
|
||||
}
|
||||
{
|
||||
linksGroups.has(CONSTANTS.SHARE_LINK_CATEGORY) && !compact ?
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
import React, { useMemo } from 'react';
|
||||
import useRating from './useRating';
|
||||
import styles from './Ratings.less';
|
||||
import Icon from '@stremio/stremio-icons/react';
|
||||
import classNames from 'classnames';
|
||||
import { IconsGroup } from 'stremio/components/IconsGroup';
|
||||
|
||||
type Props = {
|
||||
metaId?: string;
|
||||
|
|
@ -15,17 +13,20 @@ type Props = {
|
|||
const Ratings = ({ ratingInfo, className }: Props) => {
|
||||
const { onLiked, onLoved, liked, loved } = useRating(ratingInfo);
|
||||
const disabled = useMemo(() => ratingInfo?.type !== 'Ready', [ratingInfo]);
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
icon: liked ? 'thumbs-up' : 'thumbs-up-outline',
|
||||
disabled,
|
||||
onClick: onLiked,
|
||||
},
|
||||
{
|
||||
icon: loved ? 'heart' : 'heart-outline',
|
||||
disabled,
|
||||
onClick: onLoved,
|
||||
},
|
||||
], [liked, loved, disabled, onLiked, onLoved]);
|
||||
|
||||
return (
|
||||
<div className={classNames(styles['ratings-container'], className)}>
|
||||
<div className={classNames(styles['icon-container'], { [styles['disabled']]: disabled })} onClick={onLiked}>
|
||||
<Icon name={liked ? 'thumbs-up' : 'thumbs-up-outline'} className={styles['icon']} />
|
||||
</div>
|
||||
<div className={classNames(styles['icon-container'], { [styles['disabled']]: disabled })} onClick={onLoved}>
|
||||
<Icon name={loved ? 'heart' : 'heart-outline'} className={styles['icon']} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return <IconsGroup items={items} className={className} />;
|
||||
};
|
||||
|
||||
export default Ratings;
|
||||
|
|
|
|||
|
|
@ -208,11 +208,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ratings {
|
||||
margin-bottom: 1rem;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.share-prompt {
|
||||
|
|
|
|||
Loading…
Reference in a new issue