Skip to content

Commit

Permalink
Refactored setlist releases to be more similar to YARG releases
Browse files Browse the repository at this point in the history
  • Loading branch information
EliteAsian123 committed Dec 26, 2023
1 parent f03e474 commit 3b28efe
Show file tree
Hide file tree
Showing 20 changed files with 196 additions and 99 deletions.
1 change: 0 additions & 1 deletion src/components/Launch/LaunchButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { calculatePayloadPercentage } from "@app/tasks/payload";
import PayloadProgress from "../../PayloadProgress";
import Button from "@app/components/Button";
import { DropdownButton, DropdownItem } from "@app/components/DropdownButton";
// import { DropdownButton, DropdownItem } from "@app/components/DropdownButton";

interface LaunchButtonProps extends React.PropsWithChildren {
version: YARGVersion,
Expand Down
2 changes: 1 addition & 1 deletion src/components/PayloadProgress/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TaskPayload } from "@app/tasks";
import { TaskPayload } from "@app/tasks/payload";

interface Props {
payload?: TaskPayload;
Expand Down
5 changes: 1 addition & 4 deletions src/components/Queue/QueueEntry/YARG.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { YARGDownload } from "@app/tasks/Processors/YARG";
import BaseQueue from "./base";
import StableYARGIcon from "@app/assets/StableYARGIcon.png";
import NightlyYARGIcon from "@app/assets/NightlyYARGIcon.png";
import DevYARGIcon from "@app/assets/DevYARGIcon.png";
import { YARGChannels } from "@app/hooks/useYARGRelease";

interface Props {
Expand All @@ -11,11 +10,9 @@ interface Props {
}

const YARGQueue: React.FC<Props> = ({ downloader, bannerMode }: Props) => {

const channelIconPath: { [key in YARGChannels]: string } = {
"stable": StableYARGIcon,
"nightly": NightlyYARGIcon,
"newEngine": DevYARGIcon
"nightly": NightlyYARGIcon
};

return <BaseQueue
Expand Down
83 changes: 83 additions & 0 deletions src/components/Setlist/SetlistButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { ButtonColor } from "../../Button";
import { CheckmarkIcon, InstallingIcon, UpdateIcon } from "@app/assets/Icons";
import { calculatePayloadPercentage } from "@app/tasks/payload";
import PayloadProgress from "../../PayloadProgress";
import Button from "@app/components/Button";
import { DropdownButton, DropdownItem } from "@app/components/DropdownButton";
import { SetlistStates, SetlistVersion } from "@app/hooks/useSetlistData";

interface SetlistButtonProps extends React.PropsWithChildren {
version: SetlistVersion,
style?: React.CSSProperties
}

export function SetlistButton(props: SetlistButtonProps) {
const version = props.version;

if (version.state === SetlistStates.NEW_UPDATE) {
const buttonChildren = <>
<UpdateIcon /> Update Setlist
</>;

return <Button
style={props.style}
color={ButtonColor.GREEN}
onClick={() => version.download()}>

{buttonChildren}
</Button>;
}

if (version.state === SetlistStates.DOWNLOADING) {
const buttonChildren = <>
<InstallingIcon />
<PayloadProgress payload={version.payload} />
</>;

return <Button
style={props.style}
progress={calculatePayloadPercentage(version.payload)}
color={ButtonColor.YELLOW}>

{buttonChildren}
</Button>;
}

if (version.state === SetlistStates.AVAILABLE) {
const buttonChildren = <>
<CheckmarkIcon /> Downloaded
</>;

const dropdownChildren = <>
<DropdownItem>
Uninstall
</DropdownItem>
</>;

return <DropdownButton
style={props.style}
color={ButtonColor.BLUE}
dropdownChildren={dropdownChildren}>

{buttonChildren}
</DropdownButton>;
}

if (version.state === SetlistStates.ERROR) {
const buttonChildren = <>
Error!
</>;

return <Button
color={ButtonColor.RED}
style={props.style}>

{buttonChildren}
</Button>;
}

return <Button
style={props.style}>
Loading...
</Button>;
}
Original file line number Diff line number Diff line change
@@ -1,59 +1,34 @@
import { SetlistID, useSetlistRelease } from "@app/hooks/useSetlistRelease";
import { SetlistData } from "@app/hooks/useSetlistRelease";
import styles from "./setlist.module.css";
import { SetlistStates, useSetlistData } from "@app/hooks/useSetlistData";
import { SetlistVersion } from "@app/hooks/useSetlistData";
import { GenericBox, GenericBoxHeader, GenericBoxSlim } from "@app/components/GenericBox";
import SongEntry from "@app/components/Setlist/SongEntry";
import { InformationIcon, ChartersIcon, OrganizerIcon, DateIcon, SongIcon, TimeIcon, UpdateIcon, InstallingIcon, CheckmarkIcon } from "@app/assets/Icons";
import { InformationIcon, ChartersIcon, OrganizerIcon, DateIcon, SongIcon, TimeIcon } from "@app/assets/Icons";
import CreditEntry from "@app/components/Setlist/CreditEntry";
import { isConsideredNewRelease, millisToDisplayLength } from "@app/utils/timeFormat";
import Button, { ButtonColor } from "@app/components/Button";
import PayloadProgress from "@app/components/PayloadProgress";
import TooltipWrapper from "@app/components/TooltipWrapper";
import { calculatePayloadPercentage } from "@app/tasks/payload";
import { useDialogManager } from "@app/dialogs/DialogProvider";
import { intlFormatDistance } from "date-fns";
import NewsSection from "@app/components/NewsSection";
import SortChanger, { SortType } from "./SortChanger";
import SortChanger, { SortType } from "@app/components/Setlist/SortChanger";
import { useState } from "react";
import sortArray from "sort-array";
import { SetlistButton } from "@app/components/Setlist/SetlistButton";

interface Props {
setlistId: SetlistID
version: SetlistVersion,
data: SetlistData,
}

interface SetlistButtonProps extends React.PropsWithChildren {
style?: React.CSSProperties
}
const SetlistPage: React.FC<Props> = ({ version, data }: Props) => {
// If there isn't a version, something went wrong
if (!version) {
console.log(version);
return <p>Error: No version.</p>;
}

const SetlistPage: React.FC<Props> = ({ setlistId }: Props) => {
const setlistData = useSetlistRelease(setlistId);
const { state, download, payload } = useSetlistData(setlistData);
const [ sortType, setSortType ] = useState("title" as SortType);

const dialogManager = useDialogManager();

function SetlistButton(props: SetlistButtonProps) {
if (state === SetlistStates.AVAILABLE) {
return <Button style={props.style} color={ButtonColor.BLUE}>
<CheckmarkIcon /> Downloaded
</Button>;
} else if (state === SetlistStates.DOWNLOADING) {
if (!payload) {
return <></>;
}

return <Button style={props.style} progress={calculatePayloadPercentage(payload)} color={ButtonColor.YELLOW}>
<InstallingIcon />
<PayloadProgress payload={payload} />
</Button>;
} else {
return <Button style={props.style} color={ButtonColor.GREEN} onClick={() => download(dialogManager)}>
<UpdateIcon /> Update Setlist
</Button>;
}
}

const newestSongRelease = setlistData.songs.reduce((prev, curr) =>
const newestSongRelease = data.songs.reduce((prev, curr) =>
new Date(prev.releaseDate).getTime() > new Date(curr.releaseDate).getTime() ? prev : curr);

return <>
Expand All @@ -63,7 +38,7 @@ const SetlistPage: React.FC<Props> = ({ setlistId }: Props) => {
<SortChanger onChange={(s) => setSortType(s)} />

<GenericBoxSlim>
{sortArray(setlistData.songs, {
{sortArray(data.songs, {
by: "order",
order: sortType === "releaseDate" ? "desc" : "asc",
computed: {
Expand Down Expand Up @@ -93,43 +68,43 @@ const SetlistPage: React.FC<Props> = ({ setlistId }: Props) => {
<NewsSection categoryFilter="setlist_official" startingEntries={2} />
</div>
<div className={styles.sidebar}>
<SetlistButton style={{ width: "100%" }} />
<SetlistButton version={version} style={{ width: "100%" }} />
<GenericBox>
<GenericBoxHeader>
<InformationIcon />
{setlistData.locales["en-US"].title}
{data.locales["en-US"].title}
</GenericBoxHeader>

{setlistData.locales["en-US"].description}
{data.locales["en-US"].description}

<div className={styles.info_list}>
<TooltipWrapper
text={`Release Date (${intlFormatDistance(new Date(setlistData.releaseDate), new Date())})`}
text={`Release Date (${intlFormatDistance(new Date(data.releaseDate), new Date())})`}
className={styles.info_entry}>

<DateIcon />
{new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric",
}).format(new Date(setlistData.releaseDate))}
}).format(new Date(data.releaseDate))}
</TooltipWrapper>

<TooltipWrapper text="Song Count" className={styles.info_entry}>
<SongIcon />
{setlistData.songs.length} songs
{data.songs.length} songs
</TooltipWrapper>

<TooltipWrapper text="Setlist Length" className={styles.info_entry}>
<TimeIcon />
{millisToDisplayLength(setlistData.songs.reduce(
{millisToDisplayLength(data.songs.reduce(
(accumulator, currentValue) => accumulator + currentValue.length,
0), true)}
</TooltipWrapper>

<TooltipWrapper text="Organizer" className={styles.info_entry}>
<OrganizerIcon />
{setlistData.organizer}
{data.organizer}
</TooltipWrapper>
</div>
</GenericBox>
Expand All @@ -141,7 +116,7 @@ const SetlistPage: React.FC<Props> = ({ setlistId }: Props) => {
</GenericBoxHeader>

<div className={styles.info_list}>
{setlistData.credits.map(i =>
{data.credits.map(i =>
<CreditEntry creditEntry={i} key={i.name} />
)}
</div>
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions src/components/Sidebar/Versions/Setlist.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ interface Props {
}

const SetlistVersion: React.FC<Props> = ({ channel }: Props) => {
const setlistData = useSetlistRelease(channel);
const { state } = useSetlistData(setlistData);
const { data: setlistData } = useSetlistRelease(channel);
const { state } = useSetlistData(setlistData, channel);

return (
<NavLink to={"/setlist/" + channel}>
<BaseVersion
icon={<img src={OfficialIcon} />} // TO-DO: create a util/sourceIcon to get source icon from
icon={<img src={OfficialIcon} />} // TO-DO: create a util/sourceIcon to get source icon from
type={VersionType.SONG}
programName={setlistData?.locales["en-US"].title} // TO-DO: catch the BCP 47 code
versionChannel={`${setlistData?.songs?.length} songs`}
Expand Down
5 changes: 0 additions & 5 deletions src/components/Sidebar/Versions/YARG.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { YARGStates, useYARGVersion } from "@app/hooks/useYARGVersion";
import BaseVersion from "./Base";
import NightlyYARGIcon from "@app/assets/NightlyYARGIcon.png";
import StableYARGIcon from "@app/assets/StableYARGIcon.png";
import DevYARGIcon from "@app/assets/DevYARGIcon.png";
import { NavLink } from "react-router-dom";

interface Props {
Expand All @@ -20,8 +19,6 @@ const YARGVersion: React.FC<Props> = ({ channel }: Props) => {
return StableYARGIcon;
case "nightly":
return NightlyYARGIcon;
case "newEngine":
return DevYARGIcon;
}
}

Expand All @@ -31,8 +28,6 @@ const YARGVersion: React.FC<Props> = ({ channel }: Props) => {
return "Stable";
case "nightly":
return "Nightly";
case "newEngine":
return "New Engine";
}
}

Expand Down
30 changes: 23 additions & 7 deletions src/hooks/useSetlistData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,29 @@ import { SetlistData } from "./useSetlistRelease";
import { SetlistDownload } from "@app/tasks/Processors/Setlist";
import { useEffect } from "react";
import { invoke } from "@tauri-apps/api/tauri";
import { DialogManager } from "@app/dialogs";
import { showErrorDialog, showInstallFolderDialog } from "@app/dialogs/dialogUtil";
import { addTask, useTask } from "@app/tasks";
import { usePayload } from "@app/tasks/payload";
import { TaskPayload, usePayload } from "@app/tasks/payload";
import { useDialogManager } from "@app/dialogs/DialogProvider";

export enum SetlistStates {
"AVAILABLE",
"DOWNLOADING",
"ERROR",
"LOADING",
"NEW_UPDATE"
}

export const useSetlistData = (setlistData: SetlistData) => {
export type SetlistVersion = {
state: SetlistStates,
download: () => Promise<void>,
payload?: TaskPayload
}

export const useSetlistData = (setlistData: SetlistData | undefined, setlistId: string): SetlistVersion => {
const { state, setState } = useSetlistState(setlistData?.version);
const task = useTask("setlist", setlistData?.id);
const dialogManager = useDialogManager();
const task = useTask("setlist", setlistId);
const payload = usePayload(task?.taskUUID);

useEffect(() => {
Expand All @@ -34,9 +42,17 @@ export const useSetlistData = (setlistData: SetlistData) => {
setState(exists ? SetlistStates.AVAILABLE : SetlistStates.NEW_UPDATE);
}
)();
}, []);
}, [setlistData]);

// If we don't have a release data yet, return a dummy loading version;
if (!setlistData) {
return {
state,
download: async () => {},
};
}

const download = async (dialogManager: DialogManager) => {
const download = async () => {
if (!setlistData || state === SetlistStates.DOWNLOADING) return;

// Ask for a download location (if required)
Expand Down Expand Up @@ -64,5 +80,5 @@ export const useSetlistData = (setlistData: SetlistData) => {
}
};

return { state, payload, download };
return { state, download, payload };
};
2 changes: 1 addition & 1 deletion src/hooks/useSetlistRelease.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ export const useSetlistRelease = (id: SetlistID) => {
queryFn: async (): Promise<SetlistData> => await fetch(
`https://raw.githubusercontent.com/YARC-Official/Official-Setlist-Public/master/setlists/${id}.json`)
.then(res => res.json())
}).data as SetlistData;
});
};
6 changes: 2 additions & 4 deletions src/hooks/useYARGRelease.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { useQuery } from "@tanstack/react-query";
import { Endpoints } from "@octokit/types";
import { OsType } from "@tauri-apps/api/os";


export type YARGChannels = "stable" | "nightly" | "newEngine";
export type YARGChannels = "stable" | "nightly";

type ReleaseData = Endpoints["GET /repos/{owner}/{repo}/releases/latest"]["response"]["data"];
export type ExtendedReleaseData = ReleaseData & {
Expand All @@ -13,8 +12,7 @@ export type ExtendedReleaseData = ReleaseData & {
export const useYARGRelease = (channel: YARGChannels) => {
const repositoryName = {
"stable": "YARG",
"nightly": "YARG-BleedingEdge",
"newEngine": "YARG-NewEngine"
"nightly": "YARG-BleedingEdge"
};

return useQuery({
Expand Down
Loading

0 comments on commit 3b28efe

Please sign in to comment.