Skip to content

Commit

Permalink
Sort items in people view
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexPerathoner committed Oct 29, 2024
1 parent d21eb06 commit 92d334f
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 33 deletions.
3 changes: 2 additions & 1 deletion src/lib/DropDown.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
export let blendIn: boolean = false;
export let disabled = false;
export let onChange: () => void = () => {};
export let showActiveElementsInOptions: boolean = false;
let activeValue: string;
let open = false;
Expand Down Expand Up @@ -77,7 +78,7 @@
<Icon i="chevron" facing={open ? "up" : "down"} />
</button>
<ul bind:this={ulElement}>
{#each options.filter((o) => (typeof o === "string" ? o !== active : o.id !== active)) as o}
{#each options.filter( (o) => (typeof o === "string" ? showActiveElementsInOptions || o !== active : showActiveElementsInOptions || o.id !== active) ) as o}
<li>
<button
class="plain"
Expand Down
10 changes: 5 additions & 5 deletions src/lib/poster/Poster.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@
let containerEl: HTMLDivElement;
const title = media.title || media.name;
$: title = media.title || media.name;
// For now, if the content is on watched list, we can assume we have a local
// cached image. Could be improved, since we could have a cached image for
// show not on someone elses watched list.
const poster = id
$: poster = id
? `${baseURL}/img${media.poster_path}`
: `https://image.tmdb.org/t/p/w500${media.poster_path}`;
const link = media.id ? `/${media.media_type}/${media.id}` : undefined;
const dateStr = media.release_date || media.first_air_date;
const year = dateStr ? new Date(dateStr).getFullYear() : undefined;
$: link = media.id ? `/${media.media_type}/${media.id}` : undefined;
$: dateStr = media.release_date || media.first_air_date;
$: year = dateStr ? new Date(dateStr).getFullYear() : undefined;
function handleStarClick(r: number) {
if (r == rating) return;
Expand Down
116 changes: 89 additions & 27 deletions src/routes/(app)/person/[id]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import Poster from "@/lib/poster/Poster.svelte";
import PosterList from "@/lib/poster/PosterList.svelte";
import Spinner from "@/lib/Spinner.svelte";
import { removeWatched, updateWatched } from "@/lib/util/api";
import DropDown from "@/lib/DropDown.svelte";
import { getWatchedDependedProps } from "@/lib/util/helpers";
import { watchedList } from "@/store";
import type { TMDBPersonCombinedCredits, TMDBPersonDetails } from "@/types";
Expand All @@ -19,6 +19,8 @@
let personId: number | undefined;
let person: TMDBPersonDetails | undefined;
let pageError: Error | undefined;
let sortOption = "Vote count";
let credits: TMDBPersonCombinedCredits | undefined;
onMount(() => {
const unsubscribe = page.subscribe((value) => {
Expand All @@ -31,32 +33,72 @@
return unsubscribe;
});
$: {
(async () => {
try {
person = undefined;
pageError = undefined;
if (!personId) {
return;
}
const data = await getPerson(personId);
person = data;
} catch (err: any) {
person = undefined;
pageError = err;
$: if (personId) {
fetchPersonData();
}
$: if (sortOption && credits) {
sortCredits(sortOption);
}
async function fetchPersonData() {
try {
person = undefined;
pageError = undefined;
if (!personId) {
return;
}
})();
person = await getPerson(personId);
await updatePersonCredits();
sortCredits(sortOption);
} catch (err: any) {
person = undefined;
pageError = err;
}
}
async function getPerson(id: number) {
return (await axios.get(`/content/person/${id}`)).data as TMDBPersonDetails;
}
async function getPersonCredits() {
const credits = (await axios.get(`/content/person/${data.personId}/credits`))
async function updatePersonCredits() {
credits = (await axios.get(`/content/person/${data.personId}/credits`))
.data as TMDBPersonCombinedCredits;
credits.cast = credits.cast?.sort((a, b) => b.vote_count - a.vote_count);
return credits;
}
function sortCredits(sortOption: string) {
if (!credits || !credits.cast) return;
let sorted = [...credits.cast];
switch (sortOption) {
case "Vote count":
sorted.sort((a, b) => b.vote_count - a.vote_count);
break;
case "Newest":
sorted.sort((a, b) => {
const dateA = new Date(a.release_date || a.first_air_date).valueOf();
const dateB = new Date(b.release_date || b.first_air_date).valueOf();
// if a date is missing it should be sorted first since it's probably a future release
if (!a.release_date && !a.first_air_date) return -1;
if (!b.release_date && !b.first_air_date) return 1;
return dateB - dateA;
});
break;
case "Oldest":
sorted.sort((a, b) => {
const dateA = new Date(a.release_date || a.first_air_date).valueOf();
const dateB = new Date(b.release_date || b.first_air_date).valueOf();
// if a date is missing it should be sorted last since it's probably a future release
if (!a.release_date && !a.first_air_date) return 1;
if (!b.release_date && !b.first_air_date) return -1;
return dateA - dateB;
});
break;
}
credits = { ...credits, cast: sorted };
}
</script>

Expand Down Expand Up @@ -127,20 +169,26 @@
</div>
</div>
</div>

{#await getPersonCredits()}
<Spinner />
{:then credits}
<div class="filters container">
<DropDown
bind:active={sortOption}
placeholder="Vote count"
options={["Vote count", "Newest", "Oldest"]}
isDropDownItem={false}
showActiveElementsInOptions={true}
/>
</div>
{#if credits}
<div class="page">
<PosterList>
{#each credits?.cast as c}
{#each credits.cast as c}
<Poster media={c} {...getWatchedDependedProps(c.id, c.media_type, wList)} fluidSize />
{/each}
</PosterList>
</div>
{:catch err}
<Error pretty="Failed to load credits!" error={err} />
{/await}
{:else}
<Spinner />
{/if}
{:else}
person not found
{/if}
Expand All @@ -150,6 +198,20 @@
</div>

<style lang="scss">
.filters {
align-items: center;
display: flex;
justify-content: flex-end;
margin-bottom: -55px;
margin-top: 35px;
}
.container {
margin: 0 auto;
min-width: 320px;
padding-left: 20px;
padding-right: 20px;
width: 100%;
}
.content {
position: relative;
color: white;
Expand Down

0 comments on commit 92d334f

Please sign in to comment.