Skip to content

Commit

Permalink
Allow reviewing only show seasons (#1124)
Browse files Browse the repository at this point in the history
* feat(backend): change types to allow optional seasons/episodes

* feat(frontend): use select input for podcast reviewing

* fix(frontend): edge case of incorrect input

* chore(frontend): remove async where not required

* feat(frontend): use select input for show reviewing

* feat(frontend): account for show reviews that do not have episode

* fix(frontend): allow reviewing shows without any season or episode

* fix(frontend): display using default value

* fix(frontend): correct values when updating a review
  • Loading branch information
IgnisDa authored Dec 1, 2024
1 parent 4f595be commit 1271a9a
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 81 deletions.
12 changes: 7 additions & 5 deletions apps/frontend/app/components/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -483,11 +483,11 @@ export const DisplayThreePointReview = (props: {
.exhaustive();

export const ReviewItemDisplay = (props: {
review: DeepPartial<ReviewItem>;
entityLot: EntityLot;
title: string;
entityId: string;
lot?: MediaLot;
entityId: string;
entityLot: EntityLot;
review: DeepPartial<ReviewItem>;
}) => {
const userDetails = useUserDetails();
const userPreferences = useUserPreferences();
Expand Down Expand Up @@ -592,8 +592,10 @@ export const ReviewItemDisplay = (props: {
: null}
{isNumber(props.review.showExtraInformation?.season) ? (
<Text c="dimmed">
S{props.review.showExtraInformation.season}-E
{props.review.showExtraInformation.episode}
S{props.review.showExtraInformation.season}
{props.review.showExtraInformation.episode
? `-E${props.review.showExtraInformation.episode}`
: undefined}
</Text>
) : null}
{isNumber(props.review.podcastExtraInformation?.episode) ? (
Expand Down
110 changes: 69 additions & 41 deletions apps/frontend/app/routes/_dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import {
} from "@remix-run/react";
import {
CollectionExtraInformationLot,
EntityLot,
MediaLot,
type MetadataDetailsQuery,
type UserCollectionsListQuery,
Expand Down Expand Up @@ -114,6 +115,7 @@ import {
Verb,
convertDecimalToThreePointSmiley,
getLot,
getMetadataDetailsQuery,
getVerb,
refreshUserMetadataDetails,
} from "~/lib/generals";
Expand Down Expand Up @@ -147,6 +149,7 @@ import {
import { colorSchemeCookie } from "~/lib/utilities.server";
import "@mantine/dates/styles.css";
import type { LoaderFunctionArgs } from "@remix-run/node";
import { useQuery } from "@tanstack/react-query";
import Cookies from "js-cookie";
import { ClientOnly } from "remix-utils/client-only";
import { useBulkEditCollection } from "~/lib/state/collection";
Expand Down Expand Up @@ -1350,6 +1353,21 @@ const ReviewEntityForm = ({
)
: undefined,
);
const [showSeasonNumber, setShowSeasonNumber] = useState<string | undefined>(
entityToReview?.existingReview?.showExtraInformation?.season?.toString(),
);
const [showEpisodeNumber, _setShowEpisodeNumber] = useState<
string | undefined
>(entityToReview?.existingReview?.showExtraInformation?.episode?.toString());
const [podcastEpisodeNumber, _setPodcastEpisodeNumber] = useState<
string | undefined
>(
entityToReview?.existingReview?.podcastExtraInformation?.episode?.toString(),
);
const { data: metadataDetails } = useQuery({
...getMetadataDetailsQuery(entityToReview?.entityId),
enabled: entityToReview?.entityLot === EntityLot.Metadata,
});

const SmileySurround = (props: {
children: React.ReactNode;
Expand All @@ -1375,7 +1393,7 @@ const ReviewEntityForm = ({
replace
method="POST"
action={withQuery("/actions", { intent: "performReviewAction" })}
onSubmit={async (e) => {
onSubmit={(e) => {
submit(e);
refreshUserMetadataDetails(entityToReview.entityId);
events.postReview(entityToReview.entityTitle);
Expand All @@ -1387,20 +1405,21 @@ const ReviewEntityForm = ({
UserReviewScale.ThreePointSmiley && ratingInThreePointSmiley ? (
<input
hidden
readOnly
name="rating"
value={convertThreePointSmileyToDecimal(ratingInThreePointSmiley)}
readOnly
/>
) : undefined}
<input
hidden
readOnly
name="entityLot"
value={entityToReview.entityLot}
readOnly
/>
{entityToReview.existingReview?.id ? (
<input
hidden
readOnly
name="reviewId"
value={entityToReview.existingReview.id}
/>
Expand All @@ -1413,24 +1432,24 @@ const ReviewEntityForm = ({
<Input.Label>Rating:</Input.Label>
<Rating
name="rating"
fractions={2}
defaultValue={
entityToReview.existingReview?.rating
? Number(entityToReview.existingReview.rating)
: undefined
}
fractions={2}
/>
</Flex>
))
.with(UserReviewScale.OutOfHundred, () => (
<NumberInput
label="Rating"
name="rating"
w="40%"
min={0}
max={100}
step={1}
w="40%"
max={100}
hideControls
name="rating"
label="Rating"
rightSection={<IconPercentage size={16} />}
defaultValue={
entityToReview.existingReview?.rating
Expand Down Expand Up @@ -1461,45 +1480,54 @@ const ReviewEntityForm = ({
<Checkbox label="This review is a spoiler" mt="lg" name="isSpoiler" />
</Flex>
{entityToReview.metadataLot === MediaLot.Show ? (
<Flex gap="md">
<NumberInput
<Stack gap={4}>
<Select
size="xs"
clearable
searchable
limit={50}
label="Season"
name="showSeasonNumber"
hideControls
defaultValue={
isNumber(
entityToReview.existingReview?.showExtraInformation?.season,
)
? entityToReview.existingReview.showExtraInformation.season
: undefined
}
value={showSeasonNumber}
onChange={(v) => setShowSeasonNumber(v || undefined)}
data={metadataDetails?.showSpecifics?.seasons.map((s) => ({
label: `${s.seasonNumber}. ${s.name.toString()}`,
value: s.seasonNumber.toString(),
}))}
/>
<NumberInput
<Select
size="xs"
clearable
searchable
limit={50}
label="Episode"
name="showEpisodeNumber"
hideControls
defaultValue={
isNumber(
entityToReview.existingReview?.showExtraInformation?.episode,
)
? entityToReview.existingReview.showExtraInformation.episode
: undefined
value={showEpisodeNumber}
onChange={(v) => _setShowEpisodeNumber(v || undefined)}
data={
metadataDetails?.showSpecifics?.seasons
.find((s) => s.seasonNumber.toString() === showSeasonNumber)
?.episodes.map((e) => ({
label: `${e.episodeNumber}. ${e.name.toString()}`,
value: e.episodeNumber.toString(),
})) || []
}
/>
</Flex>
</Stack>
) : null}
{entityToReview.metadataLot === MediaLot.Podcast ? (
<NumberInput
<Select
clearable
limit={50}
searchable
label="Episode"
name="podcastEpisodeNumber"
hideControls
defaultValue={
isNumber(
entityToReview.existingReview?.podcastExtraInformation?.episode,
)
? entityToReview.existingReview.podcastExtraInformation.episode
: undefined
}
value={podcastEpisodeNumber}
onChange={(v) => _setPodcastEpisodeNumber(v || undefined)}
data={metadataDetails?.podcastSpecifics?.episodes.map((se) => ({
label: se.title.toString(),
value: se.number.toString(),
}))}
/>
) : null}
{entityToReview.metadataLot === MediaLot.Anime ? (
Expand Down Expand Up @@ -1631,14 +1659,14 @@ const AddEntityToCollectionForm = ({
action={withQuery("/actions", { intent: "addEntityToCollection" })}
>
<input
readOnly
hidden
readOnly
name="entityId"
value={addEntityToCollectionData.entityId}
/>
<input
readOnly
hidden
readOnly
name="entityLot"
value={addEntityToCollectionData.entityLot}
/>
Expand All @@ -1659,14 +1687,14 @@ const AddEntityToCollectionForm = ({
{selectedCollection ? (
<>
<input
readOnly
hidden
readOnly
name="collectionName"
value={selectedCollection.name}
/>
<input
readOnly
hidden
readOnly
name="creatorUserId"
value={selectedCollection.creator.id}
/>
Expand Down Expand Up @@ -1711,8 +1739,8 @@ const AddEntityToCollectionForm = ({
/>
{ownedOn ? (
<input
readOnly
hidden
readOnly
name={`information.${template.name}`}
value={formatDateToNaiveDate(ownedOn)}
/>
Expand Down
6 changes: 3 additions & 3 deletions crates/models/database/src/review.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use async_trait::async_trait;
use enums::{EntityLot, Visibility};
use media_models::{
ImportOrExportItemReviewComment, SeenAnimeExtraInformation, SeenMangaExtraInformation,
SeenPodcastExtraInformation, SeenShowExtraInformation,
SeenPodcastExtraOptionalInformation, SeenShowExtraOptionalInformation,
};
use nanoid::nanoid;
use rust_decimal::Decimal;
Expand All @@ -31,8 +31,8 @@ pub struct Model {
pub metadata_group_id: Option<String>,
pub collection_id: Option<String>,
pub exercise_id: Option<String>,
pub show_extra_information: Option<SeenShowExtraInformation>,
pub podcast_extra_information: Option<SeenPodcastExtraInformation>,
pub show_extra_information: Option<SeenShowExtraOptionalInformation>,
pub podcast_extra_information: Option<SeenPodcastExtraOptionalInformation>,
pub anime_extra_information: Option<SeenAnimeExtraInformation>,
pub manga_extra_information: Option<SeenMangaExtraInformation>,
#[sea_orm(column_type = "Json")]
Expand Down
19 changes: 17 additions & 2 deletions crates/models/media/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,21 @@ pub struct SeenPodcastExtraInformation {
pub episode: i32,
}

#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Clone, SimpleObject, FromJsonQueryResult,
)]
pub struct SeenShowExtraOptionalInformation {
pub season: Option<i32>,
pub episode: Option<i32>,
}

#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Clone, SimpleObject, FromJsonQueryResult,
)]
pub struct SeenPodcastExtraOptionalInformation {
pub episode: Option<i32>,
}

#[derive(
Debug, PartialEq, Eq, Serialize, Deserialize, Clone, SimpleObject, FromJsonQueryResult,
)]
Expand Down Expand Up @@ -878,10 +893,10 @@ pub struct ReviewItem {
pub text_rendered: Option<String>,
pub seen_items_associated_with: Vec<String>,
pub comments: Vec<ImportOrExportItemReviewComment>,
pub show_extra_information: Option<SeenShowExtraInformation>,
pub podcast_extra_information: Option<SeenPodcastExtraInformation>,
pub anime_extra_information: Option<SeenAnimeExtraInformation>,
pub manga_extra_information: Option<SeenMangaExtraInformation>,
pub show_extra_information: Option<SeenShowExtraOptionalInformation>,
pub podcast_extra_information: Option<SeenPodcastExtraOptionalInformation>,
}

#[derive(Debug, InputObject, Serialize, Deserialize, Clone)]
Expand Down
4 changes: 2 additions & 2 deletions crates/services/exporter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,10 +433,10 @@ impl ExporterService {

fn get_review_export_item(&self, rev: ReviewItem) -> ImportOrExportItemRating {
let (show_season_number, show_episode_number) = match rev.show_extra_information {
Some(d) => (Some(d.season), Some(d.episode)),
Some(d) => (d.season, d.episode),
None => (None, None),
};
let podcast_episode_number = rev.podcast_extra_information.map(|d| d.episode);
let podcast_episode_number = rev.podcast_extra_information.and_then(|d| d.episode);
let anime_episode_number = rev.anime_extra_information.and_then(|d| d.episode);
let manga_chapter_number = rev.manga_extra_information.and_then(|d| d.chapter);
ImportOrExportItemRating {
Expand Down
21 changes: 13 additions & 8 deletions crates/utils/dependent/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ use media_models::{
PartialMetadataPerson, PartialMetadataWithoutId, ProgressUpdateError,
ProgressUpdateErrorVariant, ProgressUpdateInput, ProgressUpdateResultUnion, ReviewPostedEvent,
SeenAnimeExtraInformation, SeenMangaExtraInformation, SeenPodcastExtraInformation,
SeenShowExtraInformation,
SeenPodcastExtraOptionalInformation, SeenShowExtraInformation,
SeenShowExtraOptionalInformation,
};
use nanoid::nanoid;
use providers::{
Expand Down Expand Up @@ -930,16 +931,20 @@ pub async fn post_review(
if preferences.general.disable_reviews {
return Err(Error::new("Reviews are disabled"));
}
let show_ei = if let (Some(season), Some(episode)) =
(input.show_season_number, input.show_episode_number)
{
Some(SeenShowExtraInformation { season, episode })
let show_ei = if input.show_season_number.is_some() || input.show_episode_number.is_some() {
Some(SeenShowExtraOptionalInformation {
season: input.show_season_number,
episode: input.show_episode_number,
})
} else {
None
};
let podcast_ei = input
.podcast_episode_number
.map(|episode| SeenPodcastExtraInformation { episode });
let podcast_ei =
input
.podcast_episode_number
.map(|episode| SeenPodcastExtraOptionalInformation {
episode: Some(episode),
});
let anime_ei = input
.anime_episode_number
.map(|episode| SeenAnimeExtraInformation {
Expand Down
Loading

0 comments on commit 1271a9a

Please sign in to comment.