Skip to content

Commit

Permalink
feat: desktop support (#49)
Browse files Browse the repository at this point in the history
* desktop support for search route

* playlist header desktop support

* playlist view desktop support

* library and playlist routes desktop support

* link to playlist owner through username

* improve fab

* fix playlist description margin

* only show back button in playlist when vw < sm:

* add label to navbar items

* fix typo on login page
  • Loading branch information
ExampleWasTaken authored Oct 13, 2024
1 parent 423d363 commit bba049d
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 49 deletions.
2 changes: 1 addition & 1 deletion src/components/back-button/BackButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const BackButton = ({ content }: BackButtonProps) => {
const navigate = useNavigate();

return (
<div className="flex flex-row cursor-pointer" onClick={() => navigate(-1)}>
<div className="flex flex-row cursor-pointer sm:hidden" onClick={() => navigate(-1)}>
<ChevronLeft />
<p>{content}</p>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/fab/Fab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface FabProps {
export const Fab = ({ onClick, children }: FabProps) => {
return (
<div
className="fixed bottom-20 right-6 w-14 aspect-square flex justify-center items-center drop-shadow bg-green text-black rounded-2xl cursor-pointer"
className="fixed bottom-20 right-6 min-w-14 min-h-14 px-4 flex justify-center items-center drop-shadow bg-green text-black rounded-2xl cursor-pointer"
onClick={onClick}
>
{children}
Expand Down
4 changes: 2 additions & 2 deletions src/components/list-items/PlaylistItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ interface PlaylistItemProps {

export const PlaylistItem = ({ title, owner, coverUrl }: PlaylistItemProps) => {
return (
<div className="w-full flex flex-row items-center gap-3 transition-transform ease-out active:scale-95">
<div className="group w-full flex flex-row items-center gap-3 transition-all ease-out hover:bg-subdued/20 rounded active:scale-95">
<img
className="h-14 rounded-sm"
className="h-14 rounded-sm group-hover:rounded-tr-none"
src={coverUrl}
alt={`Cover of ${title} created by ${owner}.`}
width={56}
Expand Down
2 changes: 1 addition & 1 deletion src/components/list-items/TrackListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ interface TrackListItemProps {

export const TrackListItem = ({ title, artist, explicit, coverUrl }: TrackListItemProps) => {
return (
<div className="w-full flex flex-row items-center gap-2 transition-transform ease-out active:scale-95">
<div className="cursor-default w-full flex flex-row items-center gap-2 transition-all ease-out rounded">
<img
className="h-14 aspect-square object-cover rounded-sm"
src={coverUrl}
Expand Down
8 changes: 5 additions & 3 deletions src/components/navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ export const Navbar = () => {
const iconSize = 26;

return (
<nav className="backdrop-blur bg-black/50 h-14 w-screen fixed bottom-0 left-0 flex flex-row justify-around items-center">
<Link to="/search">
<nav className="backdrop-blur bg-black/50 h-20 w-screen fixed bottom-0 left-0 flex flex-row justify-around items-center">
<Link to="/search" className="flex flex-col justify-center items-center">
<Search size={iconSize} className={clsx(currentItem === 'search' ? 'stroke-white' : 'text-subdued')} />
<p className={clsx(currentItem === 'search' ? 'text-white' : 'text-subdued')}>Search</p>
</Link>
<Link to="/library">
<Link to="/library" className="flex flex-col justify-center items-center">
<Library size={iconSize} className={clsx(currentItem === 'library' ? 'stroke-white' : 'text-subdued')} />
<p className={clsx(currentItem === 'library' ? 'text-white' : 'text-subdued')}>Library</p>
</Link>
</nav>
);
Expand Down
58 changes: 36 additions & 22 deletions src/components/playlist/PlaylistHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,35 +35,49 @@ export const PlaylistHeader = ({ playlist }: PlaylistHeaderProps) => {
});

return (
<div className="flex flex-col gap-2">
<div className="flex flex-col sm:flex-row gap-2 sm:border-b sm:border-green/50 sm:pb-4 sm:mb-2">
<img
className="w-52 rounded self-center"
src={playlist.images[0].url}
alt={`Cover of ${playlist.name} by ${playlist.owner.display_name}.`}
width={208}
height={208}
/>
<h1 className="text-lg">{playlist.name}</h1>
<p
className="text-subdued text-xs"
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(playlist.description, {
ALLOWED_ATTR: ['href', 'class'],
ALLOWED_URI_REGEXP: /^spotify:playlist:[A-Za-z0-9]+$/,
}),
}}
></p>
<div className="flex flex-row items-center gap-2">
{owner && owner.images.length > 0 && (
<img
className="h-4 rounded-full"
src={owner.images[owner.images.length - 1].url}
alt={`Profile picture of ${owner.display_name}`}
width={16}
height={16}
/>
)}
<p className="text-sm font-bold">{playlist.owner.display_name}</p>
<div className="sm:ml-3 sm:flex sm:flex-col sm:justify-between">
<div></div>
<h1 className="text-lg sm:text-3xl">{playlist.name}</h1>

<div className="sm:flex sm:flex-col sm:gap-2">
<p
className="text-subdued text-xs my-2 sm:text-sm sm:my-0"
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(playlist.description, {
ALLOWED_ATTR: ['href', 'class'],
ALLOWED_URI_REGEXP: /^spotify:playlist:[A-Za-z0-9]+$/,
}),
}}
></p>

<>
{owner && owner.images.length > 0 && (
<a
className="flex flex-row items-center gap-2"
href={owner.external_urls.spotify}
target="_blank"
rel="noreferrer noopener"
>
<img
className="h-4 rounded-full"
src={owner.images[owner.images.length - 1].url}
alt={`Profile picture of ${owner.display_name}`}
width={16}
height={16}
/>
<p className="text-sm font-bold">{playlist.owner.display_name}</p>
</a>
)}
</>
</div>
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/searchbars/mainSearchBar/MainSearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ interface MainSearchBarProps {
export const MainSearchBar = ({ onChange, suggestions }: MainSearchBarProps) => {
return (
<>
<search className="relative outline-none bg-white text-black rounded px-4 py-3 flex flex-row justify-between items-center gap-3 transition-shadow focus-within:ring focus-within:ring-green">
<search className="relative outline-none bg-white text-black rounded px-4 py-3 sm:w-96 flex flex-row justify-between items-center gap-3 transition-shadow focus-within:ring focus-within:ring-green">
<input
className="w-full placeholder-dark-subdued outline-none"
onChange={onChange}
Expand Down
7 changes: 5 additions & 2 deletions src/routes/[playlist]/Playlist.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Page, PlaylistedTrack, Playlist as SpotifyPlaylist, Track, TrackItem, User } from '@spotify/web-api-ts-sdk';
import { Save } from 'lucide-react';
import { Plus } from 'lucide-react';
import React, { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { BackButton } from '../../components/back-button/BackButton';
Expand Down Expand Up @@ -135,7 +135,10 @@ export const Playlist = () => {

{playlist && currentUser && playlist.owner.id !== currentUser.id && (
<Fab onClick={() => navigate('save')}>
<Save />
<div className="flex justify-around items-center gap-2">
<Plus className="mt-[-1px]" color="#fff" size={23} />
<p className="text-white">Save as Playlist</p>
</div>
</Fab>
)}

Expand Down
2 changes: 1 addition & 1 deletion src/routes/login/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const Login = () => {
Write access to your Spotify Library to create playlists for the songs from your mixes.
</li>
<li className="before:content-[''] before:bg-subdued before:mr-2 before:inline-block before:w-2 before:h-2 before:align-middle before:rounded-full">
Write access to your Spotify Playlists to fill playlists with the songs from your mixes.
Write access to your Spotify playlists to fill SoundDeck&apos;s playlists with the songs from your mixes.
</li>
</ul>
<p>
Expand Down
32 changes: 17 additions & 15 deletions src/routes/search/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,25 +43,27 @@ export const Search = () => {
<>
<RouteHeading title="Search" userProfilePictureUrl={currentUser.images[0].url} />

<MainSearchBar
onChange={(event) => void onSearchBarChange(event)}
suggestions={searchResults?.playlists?.items.map((playlist) => {
return (
<Link to={`/playlist/${playlist.id}`} key={playlist.id}>
<MainSearchSuggestions
title={playlist.name}
artists={playlist.owner.display_name}
coverUrl={playlist.images[0].url}
/>
</Link>
);
})}
/>
<div className="sm:flex sm:justify-center">
<MainSearchBar
onChange={(event) => void onSearchBarChange(event)}
suggestions={searchResults?.playlists?.items.map((playlist) => {
return (
<Link to={`/playlist/${playlist.id}`} key={playlist.id}>
<MainSearchSuggestions
title={playlist.name}
artists={playlist.owner.display_name}
coverUrl={playlist.images[0].url}
/>
</Link>
);
})}
/>
</div>

<h2 className="text-xl font-thin my-2">Featured Playlists</h2>

{featuredPlaylists ? (
<div className="grid grid-cols-2 sm:grid-cols-3 gap-5">
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-5 lg:grid-cols-7 gap-5">
{featuredPlaylists.playlists.items.map((playlist) => {
return (
<Link to={`/playlist/${playlist.id}`} key={playlist.id}>
Expand Down

0 comments on commit bba049d

Please sign in to comment.