Featured genre support added & CategoryCard was seperated as an independent View

This commit is contained in:
KRTirtho 2021-04-26 22:40:22 +06:00
parent c89c5a975a
commit 0dd41812ee
5 changed files with 90 additions and 58 deletions

View File

@ -10,9 +10,11 @@
"dev": "cross-env TSC_WATCHFILE=UseFsEvents webpack --mode=development",
"start": "qode ./dist/index.js",
"start:watch": "nodemon -e node -w ./*.babelrc -x \"npm start\"",
"start-dev": "concurrently -n \"webpack,spotube\" -p \"{name}-{pid}\" -c \"bgBlue,bgGreen\" -i --default-input-target spotube \"npm run dev\" \"npm run start:watch\"",
"start-dev": "concurrently -n \"webpack,spotube\" -p \"{name}-{pid}\" -c \"bgBlue.black.bold,bgGreen.black.bold\" -i --default-input-target spotube \"npm run dev\" \"npm run start:watch\"",
"debug-dev": "concurrently -n \"webpack,spotube\" -p \"{name}-{pid}\" -c \"bgBlue.black.bold,bgGreen.black.bold\" -i --default-input-target spotube \"npm run dev\" \"npm run debug:watch\"",
"start:trace": "qode ./dist/index.js --trace",
"debug": "qode --inspect ./dist/index.js",
"debug:watch": "nodemon -e node -w ./*.babelrc -x \"npm run debug\"",
"pack": "nodegui-packer -p ./dist",
"pack-deb": "node scripts/build-deb.js",
"pack-win32": "powershell.exe -ExecutionPolicy Unrestricted -Command \". '.\\scripts\\build-win32.ps1'\""

View File

@ -1,12 +1,10 @@
import React from "react";
import React, { useEffect } from "react";
import { Button, ScrollArea, View } from "@nodegui/react-nodegui";
import { useHistory } from "react-router";
import { CursorShape, QMouseEvent } from "@nodegui/nodegui";
import { QueryCacheKeys } from "../conf";
import useSpotifyQuery from "../hooks/useSpotifyQuery";
import PlaceholderApplet from "./shared/PlaceholderApplet";
import PlaylistCard from "./shared/PlaylistCard";
import useSpotifyInfiniteQuery from "../hooks/useSpotifyInfiniteQuery";
import CategoryCardView from "./shared/CategoryCardView";
function Home() {
const { data: pagedCategories, isError, refetch, isLoading, hasNextPage, isFetchingNextPage, fetchNextPage } = useSpotifyInfiniteQuery<SpotifyApi.PagingObject<SpotifyApi.CategoryObject>>(
@ -25,7 +23,7 @@ function Home() {
.map((page) => page.items)
.filter(Boolean)
.flat(1);
categories?.unshift({ href: "", icons: [], id: "featured", name: "Featured" });
return (
<ScrollArea style={`flex-grow: 1; border: none;`}>
<View style={`flex-direction: 'column'; align-items: 'center'; flex: 1;`}>
@ -33,12 +31,7 @@ function Home() {
{categories?.map((category, index) => {
return <CategoryCard key={index + category.id} id={category.id} name={category.name} />;
})}
{hasNextPage &&
<Button
on={{ clicked: () => fetchNextPage() }}
text="Load More"
enabled={!isFetchingNextPage}
/>}
{hasNextPage && <Button on={{ clicked: () => fetchNextPage() }} text="Load More" enabled={!isFetchingNextPage} />}
</View>
</ScrollArea>
);
@ -51,55 +44,21 @@ interface CategoryCardProps {
name: string;
}
const categoryStylesheet = `
#container{
flex: 1;
flex-direction: 'column';
justify-content: 'center';
}
#anchor-heading{
background: transparent;
padding: 10px;
border: none;
outline: none;
font-size: 20px;
font-weight: bold;
align-self: flex-start;
}
#child-view{
flex: 1;
}
#anchor-heading:hover{
border: none;
outline: none;
text-decoration: underline;
}
`;
const CategoryCard = ({ id, name }: CategoryCardProps) => {
const history = useHistory();
const { data: playlists, isError } = useSpotifyQuery<SpotifyApi.PlaylistObjectSimplified[]>(
[QueryCacheKeys.categoryPlaylists, id],
(spotifyApi) => spotifyApi.getPlaylistsForCategory(id, { limit: 4 }).then((playlistsRes) => playlistsRes.body.playlists.items),
async (spotifyApi) => {
const option = { limit: 4 };
let res;
if (id === "featured") {
res = await spotifyApi.getFeaturedPlaylists(option);
} else {
res = await spotifyApi.getPlaylistsForCategory(id, option);
}
return res.body.playlists.items;
},
{ initialData: [] }
);
function goToGenre(native: any) {
const mouse = new QMouseEvent(native);
if (mouse.button() === 1) {
history.push(`/genre/playlists/${id}`, { name });
}
}
if (isError) {
return <></>;
}
return (
<View id="container" styleSheet={categoryStylesheet}>
<Button id="anchor-heading" cursor={CursorShape.PointingHandCursor} on={{ MouseButtonRelease: goToGenre }} text={name} />
<View id="child-view">
{playlists?.map((playlist, index) => {
return <PlaylistCard key={index + playlist.id} playlist={playlist} />;
})}
</View>
</View>
);
return <CategoryCardView url={`/genre/playlists/${id}`} isError={isError} name={name} playlists={playlists ?? []} />;
};

View File

@ -13,7 +13,16 @@ function PlaylistGenreView() {
const location = useLocation<{ name: string }>();
const { data: pagedPlaylists, isError, isLoading, refetch, hasNextPage, isFetchingNextPage, fetchNextPage } = useSpotifyInfiniteQuery<SpotifyApi.PagingObject<SpotifyApi.PlaylistObjectSimplified>>(
[QueryCacheKeys.genrePlaylists, id],
(spotifyApi, { pageParam }) => spotifyApi.getPlaylistsForCategory(id, { limit: 20, offset: pageParam }).then((playlistsRes) => playlistsRes.body.playlists),
async (spotifyApi, { pageParam }) => {
const option = { limit: 20, offset: pageParam };
let res;
if (id === "featured") {
res = await spotifyApi.getFeaturedPlaylists(option);
} else {
res = await spotifyApi.getPlaylistsForCategory(id, option);
}
return res.body.playlists;
},
{
getNextPageParam(lastPage) {
if (lastPage.next) {

View File

@ -0,0 +1,61 @@
import { QMouseEvent, CursorShape } from "@nodegui/nodegui";
import { View, Button } from "@nodegui/react-nodegui";
import React, { FC } from "react";
import { useHistory } from "react-router";
import PlaylistCard from "./PlaylistCard";
interface CategoryCardProps {
url: string;
name: string;
isError: boolean;
playlists: SpotifyApi.PlaylistObjectSimplified[];
}
const categoryStylesheet = `
#container{
flex: 1;
flex-direction: 'column';
justify-content: 'center';
}
#anchor-heading{
background: transparent;
padding: 10px;
border: none;
outline: none;
font-size: 20px;
font-weight: bold;
align-self: flex-start;
}
#child-view{
flex: 1;
}
#anchor-heading:hover{
border: none;
outline: none;
text-decoration: underline;
}
`;
const CategoryCard: FC<CategoryCardProps> = ({ name, isError, playlists, url }) => {
const history = useHistory();
function goToGenre(native: any) {
const mouse = new QMouseEvent(native);
if (mouse.button() === 1) {
history.push(url, { name });
}
}
if (isError) {
return <></>;
}
return (
<View id="container" styleSheet={categoryStylesheet}>
<Button id="anchor-heading" cursor={CursorShape.PointingHandCursor} on={{ MouseButtonRelease: goToGenre }} text={name} />
<View id="child-view">
{playlists.map((playlist, index) => {
return <PlaylistCard key={index + playlist.id} playlist={playlist} />;
})}
</View>
</View>
);
};
export default CategoryCard;

View File

@ -12,6 +12,7 @@ export const cacheDir = join(homedir(), ".cache", "spotube")
export enum QueryCacheKeys{
categories="categories",
categoryPlaylists = "categoryPlaylists",
featuredPlaylists = "featuredPlaylists",
genrePlaylists="genrePlaylists",
playlistTracks="playlistTracks",
userPlaylists = "user-palylists",