Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
@width-mobile: 3rem;


.ratings-container {
.group-container {
display: flex;
flex-direction: row;
align-items: center;
Expand Down Expand Up @@ -45,7 +45,7 @@
}

@media @phone-landscape {
.ratings-container {
.group-container {
height: @height-mobile;

.icon-container {
Expand Down
39 changes: 39 additions & 0 deletions src/components/ActionsGroup/ActionsGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// 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 './ActionsGroup.less';
import { Tooltip } from 'stremio/common/Tooltips';

type Item = {
icon: string;
label?: string;
filled?: string;
disabled?: boolean;
className?: string;
onClick?: () => void;
};

type Props = {
items: Item[];
className?: string;
};

const ActionsGroup = ({ 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}
>
{item.label && <Tooltip label={item.label} position={'top'} />}
<Icon name={item.icon} className={styles['icon']} />
</div>
))}
</div>
);
};

export default ActionsGroup;
6 changes: 6 additions & 0 deletions src/components/ActionsGroup/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright (C) 2017-2023 Smart code 203358507

import ActionsGroup from './ActionsGroup';

export { ActionsGroup };

37 changes: 22 additions & 15 deletions src/components/MetaPreview/MetaPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 { ActionsGroup } = require('stremio/components/ActionsGroup');
const ModalDialog = require('stremio/components/ModalDialog');
const SharePrompt = require('stremio/components/SharePrompt');
const CONSTANTS = require('stremio/common/CONSTANTS');
Expand All @@ -25,7 +26,7 @@ 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, ratingInfo }, ref) => {
const MetaPreview = React.forwardRef(({ className, compact, name, logo, background, runtime, releaseInfo, released, description, deepLinks, links, trailerStreams, inLibrary, toggleInLibrary, watched, toggleWatched, ratingInfo }, ref) => {
const { t } = useTranslation();
const [shareModalOpen, openShareModal, closeShareModal] = useBinaryState(false);
const linksGroups = React.useMemo(() => {
Expand Down Expand Up @@ -98,6 +99,18 @@ const MetaPreview = React.forwardRef(({ className, compact, name, logo, backgrou
const renderLogoFallback = React.useCallback(() => (
<div className={styles['logo-placeholder']}>{name}</div>
), [name]);
const metaItemActions = React.useMemo(() => [
{
icon: inLibrary ? 'remove-from-library' : 'add-to-library',
label: inLibrary ? t('REMOVE_FROM_LIB') : t('ADD_TO_LIB'),
onClick: typeof toggleInLibrary === 'function' ? toggleInLibrary : null,
},
{
icon: watched ? 'eye-off' : 'eye',
label: watched ? t('CTX_MARK_UNWATCHED') : t('CTX_MARK_WATCHED'),
onClick: typeof toggleWatched === 'function' ? toggleWatched : undefined,
},
], [inLibrary, watched, toggleInLibrary, toggleWatched]);
return (
<div className={classnames(className, styles['meta-preview-container'], { [styles['compact']]: compact })} ref={ref}>
{
Expand Down Expand Up @@ -195,19 +208,6 @@ const MetaPreview = React.forwardRef(({ className, compact, name, logo, backgrou
}
</div>
<div className={styles['action-buttons-container']}>
{
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 trailerHref === 'string' ?
<ActionButton
Expand All @@ -221,6 +221,11 @@ const MetaPreview = React.forwardRef(({ className, compact, name, logo, backgrou
:
null
}
{
typeof toggleInLibrary === 'function' && typeof toggleWatched === 'function'
? <ActionsGroup items={metaItemActions} className={styles['group-container']} />
: null
}
{
typeof showHref === 'string' && compact ?
<ActionButton
Expand All @@ -237,7 +242,7 @@ const MetaPreview = React.forwardRef(({ className, compact, name, logo, backgrou
!compact && ratingInfo !== null ?
<Ratings
ratingInfo={ratingInfo}
className={styles['ratings']}
className={styles['group-container']}
/>
:
null
Expand Down Expand Up @@ -298,6 +303,8 @@ MetaPreview.propTypes = {
trailerStreams: PropTypes.array,
inLibrary: PropTypes.bool,
toggleInLibrary: PropTypes.func,
watched: PropTypes.bool,
toggleWatched: PropTypes.func,
ratingInfo: PropTypes.object,
};

Expand Down
27 changes: 14 additions & 13 deletions src/components/MetaPreview/Ratings/Ratings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 { ActionsGroup } from 'stremio/components/ActionsGroup';

type Props = {
metaId?: string;
Expand All @@ -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 <ActionsGroup items={items} className={className} />;
};

export default Ratings;
25 changes: 15 additions & 10 deletions src/components/MetaPreview/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
.action-buttons-container {
justify-content: space-between;

.action-button:not(:last-child) {
.action-button:not(:last-child), .group-container:not(:last-child) {
margin-right: 0;
}
}
Expand Down Expand Up @@ -207,11 +207,20 @@
}
}
}
}

.group-container {
margin-bottom: 1rem;

.ratings {
margin-bottom: 1rem;
margin-right: 1rem;
&:global(.wide) {
width: auto;
padding: 0 2rem;
border-radius: 4rem;
}

&:not(:last-child) {
margin-right: 1rem;
}
}
}
}

Expand All @@ -233,17 +242,13 @@
padding-top: 1.5rem;
gap: 0.5rem;

.action-button {
.action-button, .group-container {
padding: 0 1.5rem !important;
margin-right: 0rem !important;
height: 3rem;
border-radius: 2rem;
}
}

.ratings {
margin-right: 0;
}
}
}

Expand Down
18 changes: 18 additions & 0 deletions src/routes/Discover/Discover.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,22 @@ const Discover = ({ urlParams, queryParams }) => {
}
});
}, [selectedMetaItem]);
const toggleWatched = React.useCallback(() => {
if (selectedMetaItem === null) {
return;
}

core.transport.dispatch({
action: 'Ctx',
args: {
action: 'LibraryItemMarkAsWatched',
args: {
id: selectedMetaItem.id,
is_watched: !selectedMetaItem.watched
}
}
});
}, [selectedMetaItem]);
const metaItemsOnFocusCapture = React.useCallback((event) => {
if (event.target.dataset.index !== null && !isNaN(event.target.dataset.index)) {
setSelectedMetaItemIndex(parseInt(event.target.dataset.index, 10));
Expand Down Expand Up @@ -193,6 +209,8 @@ const Discover = ({ urlParams, queryParams }) => {
trailerStreams={selectedMetaItem.trailerStreams}
inLibrary={selectedMetaItem.inLibrary}
toggleInLibrary={selectedMetaItem.inLibrary ? removeFromLibrary : addToLibrary}
watched={selectedMetaItem.watched}
toggleWatched={toggleWatched}
metaId={selectedMetaItem.id}
like={selectedMetaItem.like}
/>
Expand Down
18 changes: 18 additions & 0 deletions src/routes/MetaDetails/MetaDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,22 @@ const MetaDetails = ({ urlParams, queryParams }) => {
}
});
}, [metaDetails]);
const toggleWatched = React.useCallback(() => {
if (metaDetails.metaItem.content.content === null || metaDetails.metaItem.content.type !== 'Ready') {
return;
}

core.transport.dispatch({
action: 'Ctx',
args: {
action: 'LibraryItemMarkAsWatched',
args: {
id: metaDetails.metaItem.content.content.id,
is_watched: !metaDetails.metaItem.content.content.watched
}
}
});
}, [metaDetails]);
const toggleNotifications = React.useCallback(() => {
if (metaDetails.libraryItem) {
core.transport.dispatch({
Expand Down Expand Up @@ -168,6 +184,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}
watched={metaDetails.metaItem.content.content.watched}
toggleWatched={toggleWatched}
metaId={metaDetails.metaItem.content.content.id}
ratingInfo={metaDetails.ratingInfo}
/>
Expand Down