Customize recommendations (#2592)

* refactored common code in recommendation row
* Implement front page options in config
* Allow customisation from front page
* Rename recommendations to front page
* Add generic UI settings
* Support adding premade filters

Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
CJ
2022-06-13 19:34:04 -05:00
committed by GitHub
parent ff724d82cc
commit 9264c15540
38 changed files with 1549 additions and 292 deletions

View File

@@ -1,45 +1,63 @@
import React, { FunctionComponent } from "react";
import { FindScenesQueryResult } from "src/core/generated-graphql";
import React, { FunctionComponent, useMemo } from "react";
import { useFindScenes } from "src/core/StashService";
import Slider from "react-slick";
import { SceneCard } from "./SceneCard";
import { SceneQueue } from "src/models/sceneQueue";
import { ListFilterModel } from "src/models/list-filter/filter";
import { getSlickSliderSettings } from "src/core/recommendations";
import { RecommendationRow } from "../FrontPage/RecommendationRow";
import { FormattedMessage } from "react-intl";
interface IProps {
isTouch: boolean;
filter: ListFilterModel;
result: FindScenesQueryResult;
queue: SceneQueue;
header: String;
linkText: String;
}
export const SceneRecommendationRow: FunctionComponent<IProps> = (
props: IProps
) => {
const cardCount = props.result.data?.findScenes.count;
const result = useFindScenes(props.filter);
const cardCount = result.data?.findScenes.count;
const queue = useMemo(() => {
return SceneQueue.fromListFilterModel(props.filter);
}, [props.filter]);
if (!result.loading && !cardCount) {
return null;
}
return (
<div className="recommendation-row scene-recommendations">
<div className="recommendation-row-head">
<div>
<h2>{props.header}</h2>
</div>
<RecommendationRow
className="scene-recommendations"
header={props.header}
link={
<a href={`/scenes?${props.filter.makeQueryParameters()}`}>
{props.linkText}
<FormattedMessage id="view_all" />
</a>
</div>
<Slider {...getSlickSliderSettings(cardCount!, props.isTouch)}>
{props.result.data?.findScenes.scenes.map((scene, index) => (
<SceneCard
key={scene.id}
scene={scene}
queue={props.queue}
index={index}
zoomIndex={1}
/>
))}
}
>
<Slider
{...getSlickSliderSettings(
cardCount ? cardCount : props.filter.itemsPerPage,
props.isTouch
)}
>
{result.loading
? [...Array(props.filter.itemsPerPage)].map((i) => (
<div key={i} className="scene-skeleton skeleton-card"></div>
))
: result.data?.findScenes.scenes.map((scene, index) => (
<SceneCard
key={scene.id}
scene={scene}
queue={queue}
index={index}
zoomIndex={1}
/>
))}
</Slider>
</div>
</RecommendationRow>
);
};