Skip to content

Commit

Permalink
add sort dropdown
Browse files Browse the repository at this point in the history
  • Loading branch information
gregrickaby committed Feb 13, 2024
1 parent b78e194 commit 3c8bfe8
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 11 deletions.
10 changes: 10 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@
@apply h-16 w-full text-xl outline-1 dark:outline-zinc-900;
}

.select-wrapper {
@apply relative inline-block;
}

.select-wrapper::after {
@apply pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-sm;

content: '▼';
}

button,
.button {
@apply leading-tight no-underline;
Expand Down
4 changes: 2 additions & 2 deletions app/r/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ export default async function Page(props: PageProps) {

// Get the search parameters.
const limit = props.searchParams.limit || config.redditApi.limit
const sortBy = props.searchParams.sortBy || config.redditApi.sortBy
const sort = props.searchParams.sort || config.redditApi.sort
let after = props.searchParams.after || ''

// Fetch the subreddit posts.
const posts = await fetchSubredditPosts({slug, sortBy, limit, after})
const posts = await fetchSubredditPosts({slug, sort, limit, after})

// Error? Bail.
if (posts.error || !posts.data) {
Expand Down
32 changes: 28 additions & 4 deletions components/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {IconX} from '@tabler/icons-react'
import Link from 'next/link'
import {usePathname, useRouter} from 'next/navigation'
import {useCallback, useEffect, useRef, useState} from 'react'
import config from '@/lib/config'

/**
* Debounce a callback.
Expand All @@ -30,6 +31,7 @@ export default function Search() {
const inputRef = useRef<HTMLInputElement>(null)

const [query, setQuery] = useState(initialSubreddit || '')
const [searchFilter, setSearchFilter] = useState(config.redditApi.sort)
const [results, setResults] = useState<RedditSearchResponse>({})
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
const [selectedIndex, setSelectedIndex] = useState(0)
Expand All @@ -41,6 +43,11 @@ export default function Search() {
setIsDrawerOpen(!!inputQuery)
}

const handleFilterChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
setSearchFilter(e.target.value)
router.push(`${pathname}?sort=${e.target.value}`)
}

const performSearch = useCallback(async () => {
if (query.length < 2) return
const results = await fetchSearchResults(query)
Expand All @@ -54,6 +61,7 @@ export default function Search() {
setResults({})
setIsDrawerOpen(false)
setSelectedIndex(0)
setSearchFilter(config.redditApi.sort)
}

useEffect(() => {
Expand All @@ -70,7 +78,7 @@ export default function Search() {
} else if (e.key === 'Enter' && itemCount > 0) {
const selectedResult = results?.data?.children[selectedIndex]
if (selectedResult) {
router.push(selectedResult.data.url)
router.push(`${selectedResult.data.url}?sort=${searchFilter}`)
resetSearch()
}
e.preventDefault()
Expand All @@ -79,7 +87,7 @@ export default function Search() {

window.addEventListener('keydown', handleKeyDown)
return () => window.removeEventListener('keydown', handleKeyDown)
}, [isDrawerOpen, results, selectedIndex, router])
}, [isDrawerOpen, results, selectedIndex, router, searchFilter])

useEffect(() => {
if (pathname === '/' || !initialSubreddit) {
Expand Down Expand Up @@ -110,14 +118,27 @@ export default function Search() {
{query.length > 0 && (
<button
aria-label="clear search"
className="absolute right-2 z-10 rounded bg-zinc-400 p-1 font-mono text-xs text-zinc-200 transition-all duration-300 ease-in-out hover:bg-zinc-600 dark:bg-zinc-700 dark:text-zinc-400"
className="absolute right-28 z-10 rounded bg-zinc-400 p-1 font-mono text-xs text-zinc-200 transition-all duration-300 ease-in-out hover:bg-zinc-600 dark:bg-zinc-700 dark:text-zinc-400"
onClick={resetSearch}
type="reset"
>
<IconX />
</button>
)}

<div className="select-wrapper">
<select
className="ml-2 h-16 appearance-none rounded px-4 py-2 outline-none"
onChange={handleFilterChange}
value={searchFilter}
>
<option value="hot">Hot</option>
<option value="new">New</option>
<option value="top">Top</option>
<option value="rising">Rising</option>
</select>
</div>

{isDrawerOpen && results && (
<ul className="absolute left-0 top-16 z-50 m-0 w-full list-none rounded-b bg-zinc-200 p-0 dark:bg-zinc-700">
{results?.data?.children?.map(
Expand All @@ -126,7 +147,10 @@ export default function Search() {
<li className="m-0 p-0" key={data.id}>
<Link
className={`m-0 flex items-center justify-start gap-2 p-1 hover:bg-zinc-300 hover:no-underline dark:hover:bg-zinc-800 ${selectedIndex === index ? 'bg-zinc-300 dark:bg-zinc-800' : ''}`}
href={data.url || ''}
href={{
pathname: data.url,
query: {sort: searchFilter}
}}
onClick={resetSearch}
prefetch={false}
>
Expand Down
4 changes: 2 additions & 2 deletions lib/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,14 @@ export async function fetchSubredditPosts(
): Promise<RedditPostResponse> {
try {
// Destructure props.
const {slug, sortBy, limit, after} = props
const {slug, sort, limit, after} = props

// Fetch the Reddit oAuth token.
const {access_token} = await fetchToken()

// Fetch the subreddit posts.
const response = await fetch(
`https://oauth.reddit.com/r/${slug}/${sortBy}/.json?limit=${limit}&after=${after}&raw_json=1`,
`https://oauth.reddit.com/r/${slug}/${sort}/.json?limit=${limit}&after=${after}&raw_json=1`,
{
headers: {
'User-Agent': config.userAgent,
Expand Down
2 changes: 1 addition & 1 deletion lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const config = {
redditApi: {
popularLimit: '5',
limit: '50',
sortBy: 'hot',
sort: 'hot',
sub: 'itookapicture'
},
cacheTtl: 3600
Expand Down
4 changes: 2 additions & 2 deletions lib/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,14 @@ export interface ImageAsset {

export interface FetchSubredditProps {
slug: string
sortBy: string
sort: string
limit: number | string
after: string
}

export interface PageProps {
params: {slug: string}
searchParams: {before: string; after: string; limit: number; sortBy: string}
searchParams: {before: string; after: string; limit: number; sort: string}
}

export interface HlsPlayerProps
Expand Down

0 comments on commit 3c8bfe8

Please sign in to comment.