Skip to content

Commit

Permalink
feat: button to add songs from statistics to queue
Browse files Browse the repository at this point in the history
  • Loading branch information
miksuh-dev committed Apr 9, 2023
1 parent d57ea19 commit cacb6f8
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 4 deletions.
27 changes: 25 additions & 2 deletions client/src/view/Room/List/Statistics/Statistics.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
import { useI18n } from "@solid-primitives/i18n";
import { CircularLoadingSpinner } from "components/common/icon";
import { Accessor, Component, For, Show } from "solid-js";
import { Statistic } from "trpc/types";
import { AddSongInput, PlayingSong, Song, Statistic } from "trpc/types";
import { htmlDecode } from "utils/parse";
import SongThumbnail from "view/Room/common/SongThumbnail";

type Props = {
statistics: Accessor<Statistic[]>;
songs: Song[];
playing: PlayingSong;
onAdd: (song: AddSongInput) => void;
loading: Accessor<boolean>;
};

const StatisticsComponent: Component<Props> = (props) => {
const [t] = useI18n();

const isInQueue = (song: Statistic) => {
return (
props.songs.some((s) => s.contentId === song.contentId) ||
(props.playing && props.playing.contentId === song.contentId)
);
};

return (
<div class="space-y h-full max-h-full space-y-2 overflow-y-auto pr-4">
<Show
Expand All @@ -27,7 +37,7 @@ const StatisticsComponent: Component<Props> = (props) => {
>
<For each={props.statistics()}>
{(statistic, index) => (
<div class="card flex w-full items-center justify-between p-2 px-4">
<div class="card flex w-full items-center justify-between space-x-2 p-2 px-4">
<div class="flex items-center space-x-4">
<div class="w-4 flex-shrink-0">{index() + 1}</div>
<SongThumbnail song={statistic} />
Expand All @@ -42,6 +52,19 @@ const StatisticsComponent: Component<Props> = (props) => {
</div>
</div>
</div>
<button
type="button"
class="ml-auto inline-flex shrink-0 items-center rounded border border-transparent bg-custom-primary-900 px-2.5 py-1.5 text-xs font-medium text-white hover:bg-custom-primary-800 focus:outline-none focus:ring-2 focus:ring-custom-primary-500 focus:ring-offset-2 dark:bg-custom-primary-900 dark:hover:bg-custom-primary-800 dark:focus:ring-custom-primary-500"
onClick={() => props.onAdd([statistic])}
disabled={isInQueue(statistic)}
>
<Show
when={!isInQueue(statistic)}
fallback={t("common.inQueue")}
>
{t("actions.addToQueue")}
</Show>
</button>
</div>
)}
</For>
Expand Down
40 changes: 38 additions & 2 deletions client/src/view/Room/List/Statistics/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { useI18n } from "@solid-primitives/i18n";
import { useRouteData } from "@solidjs/router";
import { TabContainer } from "components/Tabs";
import useSnackbar from "hooks/useSnackbar";
import { DateTime } from "luxon";
import { Component, createSignal, onMount } from "solid-js";
import trpcClient from "trpc";
import { Statistic, StatisticsInput } from "trpc/types";
import { AddSongInput, Statistic, StatisticsInput } from "trpc/types";
import { htmlDecode } from "utils/parse";
import { RoomData } from "view/Room/data";
import Filter from "./Filter";
import Statistics from "./Statistics";

Expand All @@ -15,6 +18,7 @@ export type FormData = {
const StatisticsComponent: Component = () => {
const snackbar = useSnackbar();
const [t] = useI18n();
const { room } = useRouteData<RoomData>();

const [loading, setLoading] = createSignal(false);
const [formData, setFormData] = createSignal<FormData>({
Expand Down Expand Up @@ -45,6 +49,32 @@ const StatisticsComponent: Component = () => {
}
};

const handleAdd = async (result: AddSongInput) => {
try {
const songs = await trpcClient.room.addSong.mutate(
result.map((r) => ({
contentId: r.contentId,
url: r.url,
title: r.title,
thumbnail: r.thumbnail ?? null,
type: r.type,
}))
);

const song = songs[0];

snackbar.success(
t(`snackbar.source.${song.type}.addedToQueue`, {
item: htmlDecode(song.title),
})
);
} catch (error) {
if (error instanceof Error) {
snackbar.error(t("snackbar.error", { error: error.message }));
}
}
};

return (
<TabContainer
actions={
Expand All @@ -59,7 +89,13 @@ const StatisticsComponent: Component = () => {
/>
}
>
<Statistics statistics={result} loading={loading} />
<Statistics
statistics={result}
songs={room().songs}
playing={room().playing}
onAdd={handleAdd}
loading={loading}
/>
</TabContainer>
);
};
Expand Down

0 comments on commit cacb6f8

Please sign in to comment.