Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.0.2 bug hunting #302

Merged
merged 4 commits into from Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/server/src/routers/api/v1/media.rs
Expand Up @@ -787,7 +787,7 @@ async fn get_media_file(
) -> APIResult<NamedFile> {
let db = &ctx.db;

let user = get_session_user(&session)?;
let user = enforce_session_permissions(&session, &[UserPermission::DownloadFile])?;
let age_restrictions = user
.age_restriction
.as_ref()
Expand Down Expand Up @@ -836,6 +836,7 @@ async fn convert_media(
) -> Result<(), APIError> {
let db = &ctx.db;

// TODO: if keeping, enforce permission
let user = get_session_user(&session)?;
let age_restrictions = user
.age_restriction
Expand Down
33 changes: 24 additions & 9 deletions packages/browser/src/components/Pagination.tsx
@@ -1,18 +1,19 @@
import { cn, cx } from '@stump/components'
import { ArrowLeft, ArrowRight, MoreHorizontal } from 'lucide-react'
import { useMemo } from 'react'
import { useCallback, useMemo } from 'react'
import { useWindowSize } from 'rooks'

import { usePagination } from '../hooks/usePagination'
import PagePopoverForm from './PagePopoverForm'

interface PaginationArrowProps {
type PaginationArrowProps = {
kind: 'previous' | 'next'
isDisabled?: boolean
onClick: () => void
onMouseEnter?: () => void
}

function PaginationArrow({ kind, isDisabled, onClick }: PaginationArrowProps) {
function PaginationArrow({ kind, isDisabled, onClick, onMouseEnter }: PaginationArrowProps) {
const ArrowIcon = kind === 'previous' ? ArrowLeft : ArrowRight

// NOTE: notice I am wrapping the link (which will have pointer-events-none when
Expand All @@ -23,6 +24,7 @@ function PaginationArrow({ kind, isDisabled, onClick }: PaginationArrowProps) {
className={cx('items-center', kind === 'next' ? 'justify-end text-right' : 'justify-start', {
'cursor-not-allowed': isDisabled,
})}
onMouseEnter={!isDisabled ? onMouseEnter : undefined}
>
<button
onClick={onClick}
Expand Down Expand Up @@ -56,16 +58,18 @@ function PaginationArrow({ kind, isDisabled, onClick }: PaginationArrowProps) {
)
}

interface PaginationLinkProps {
type PaginationLinkProps = {
onClick?: () => void
value: number
isActive: boolean
onMouseEnter?: () => void
}

function PaginationLink({ value, onClick, isActive }: PaginationLinkProps) {
function PaginationLink({ value, onClick, isActive, onMouseEnter }: PaginationLinkProps) {
return (
<span
onClick={onClick}
onMouseEnter={onMouseEnter}
className={cn(
'inline-flex cursor-pointer items-center border-t-2 px-4 pt-4 text-xs font-medium text-muted md:text-sm',
{
Expand All @@ -81,18 +85,20 @@ function PaginationLink({ value, onClick, isActive }: PaginationLinkProps) {
)
}

export interface PaginationProps {
export type PaginationProps = {
position?: 'top' | 'bottom'
pages: number
currentPage: number
onChangePage: (page: number) => void
onPrefetchPage?: (page: number) => void
}

export default function Pagination({
position = 'top',
pages,
currentPage,
onChangePage,
onPrefetchPage,
}: PaginationProps) {
const { innerWidth: screenWidth } = useWindowSize()

Expand All @@ -112,9 +118,15 @@ export default function Pagination({

const { pageRange } = usePagination({ currentPage, numbersToShow, totalPages: pages })

function handleEllipsisNavigate(page: number) {
onChangePage(page)
}
const handleEllipsisNavigate = useCallback(
(page: number) => {
onPrefetchPage?.(page)
onChangePage(page)
},
[onChangePage, onPrefetchPage],
)

const handlePrefetchPage = useCallback((page: number) => onPrefetchPage?.(page), [onPrefetchPage])

return (
<nav className="w-full">
Expand All @@ -128,6 +140,7 @@ export default function Pagination({
kind="previous"
onClick={() => onChangePage(currentPage - 1)}
isDisabled={currentPage === 1}
onMouseEnter={() => handlePrefetchPage(currentPage - 1)}
/>

<div className="flex items-center">
Expand All @@ -137,6 +150,7 @@ export default function Pagination({
<PaginationLink
key={`${i}, pagination-${page}`}
onClick={() => onChangePage(page)}
onMouseEnter={() => handlePrefetchPage(page)}
isActive={page === currentPage}
value={page}
/>
Expand Down Expand Up @@ -165,6 +179,7 @@ export default function Pagination({
<PaginationArrow
kind="next"
onClick={() => onChangePage(currentPage + 1)}
onMouseEnter={() => handlePrefetchPage(currentPage + 1)}
isDisabled={currentPage >= pages}
/>
</div>
Expand Down
33 changes: 25 additions & 8 deletions packages/browser/src/components/media/BookSearch.tsx
@@ -1,7 +1,7 @@
import { usePagedMediaQuery } from '@stump/client'
import { prefetchPagedMedia, usePagedMediaQuery } from '@stump/client'
import { usePreviousIsDifferent } from '@stump/components'
import { Media } from '@stump/types'
import React, { useEffect } from 'react'
import React, { useCallback, useEffect, useMemo } from 'react'

import useIsInView from '@/hooks/useIsInView'

Expand All @@ -23,16 +23,21 @@ type Props = {
*/
export default function BookSearch({ page, page_size, setPage, onBookSelect, showFilters }: Props) {
const { filters } = useFilterContext()

const params = useMemo(
() => ({
page,
page_size,
params: filters,
}),
[page, page_size, filters],
)
const {
isLoading,
isRefetching,
media,
pageData: { current_page, total_pages } = {},
} = usePagedMediaQuery({
page,
page_size,
params: filters,
})
} = usePagedMediaQuery(params)

const differentSearch = usePreviousIsDifferent(filters?.search as string)
useEffect(() => {
Expand All @@ -58,6 +63,16 @@ export default function BookSearch({ page, page_size, setPage, onBookSelect, sho
const hasStuff = total_pages !== undefined && current_page !== undefined && total_pages > 0
const hasFilters = Object.keys(filters || {}).length > 0

const handlePrefetchPage = useCallback(
(page: number) => {
prefetchPagedMedia({
...params,
page,
})
},
[params],
)

return (
<>
<section ref={containerRef} id="grid-top-indicator" className="h-1" />
Expand All @@ -68,12 +83,13 @@ export default function BookSearch({ page, page_size, setPage, onBookSelect, sho
{...(showFilters ? { entity: 'media', orderBy: true } : {})}
/>

<div className="flex w-full flex-col space-y-6 pt-4">
<div className="flex w-full flex-col space-y-6 pb-[64px] pt-4 md:pb-0">
{hasStuff && (
<Pagination
pages={total_pages}
currentPage={current_page}
onChangePage={(page) => setPage(page)}
onPrefetchPage={handlePrefetchPage}
/>
)}
<MediaGrid
Expand All @@ -88,6 +104,7 @@ export default function BookSearch({ page, page_size, setPage, onBookSelect, sho
pages={total_pages}
currentPage={current_page}
onChangePage={(page) => setPage(page)}
onPrefetchPage={handlePrefetchPage}
/>
)}
</div>
Expand Down
Expand Up @@ -12,12 +12,12 @@ export const TOPBAR_HEIGHT_PX = 53
*/
export default function TopBar() {
return (
<header className="sticky top-0 z-10 flex h-[50px] w-full border-b border-edge-200 bg-sidebar px-4 md:hidden">
<header className="sticky top-0 z-10 flex h-14 w-full shrink-0 border-b border-edge-200 bg-sidebar px-4 md:hidden">
<div className="grid w-full grid-cols-8 items-center gap-2">
<div className="col-span-1">
<MobileSheet />
</div>
<div className="col-span-6 flex items-center justify-center gap-2">
<div className="col-span-6 flex h-full items-center justify-center gap-2">
<Link to="/" className="flex shrink-0 items-center justify-start gap-2">
<img src="/assets/favicon.ico" className="h-6 w-6 object-scale-down" />
<Heading variant="gradient" size="xs">
Expand Down
1 change: 1 addition & 0 deletions packages/browser/src/scenes/home/HomeScene.tsx
Expand Up @@ -38,6 +38,7 @@ export default function HomeScene() {
<ContinueReadingMedia />
<RecentlyAddedMedia />
<RecentlyAddedSeries />
<div className="pb-5 sm:pb-0" />
</SceneContainer>
)
}
52 changes: 37 additions & 15 deletions packages/browser/src/scenes/library/LibraryBooksScene.tsx
@@ -1,5 +1,5 @@
import { usePagedMediaQuery } from '@stump/client'
import { useEffect } from 'react'
import { prefetchPagedMedia, usePagedMediaQuery } from '@stump/client'
import { useCallback, useEffect, useMemo } from 'react'
import { Helmet } from 'react-helmet'
import { useMediaMatch } from 'rooks'

Expand Down Expand Up @@ -31,28 +31,44 @@ function LibraryBooksScene() {

const { layoutMode } = useLayoutMode()
const { filters } = useFilterContext()

const params = useMemo(
() => ({
page,
page_size: is3XLScreenOrBigger ? 40 : 20,
params: {
...filters,
series: {
library: {
id: library.id,
},
},
},
}),
[page, is3XLScreenOrBigger, filters, library.id],
)
const {
isLoading: isLoadingMedia,
isRefetching: isRefetchingMedia,
media,
pageData,
} = usePagedMediaQuery({
page,
page_size: is3XLScreenOrBigger ? 40 : 20,
params: {
...filters,
series: {
library: {
id: library.id,
},
},
},
})
} = usePagedMediaQuery(params)

const { current_page, total_pages } = pageData || {}

const isOnFirstPage = current_page === 1
const hasStuff = total_pages !== undefined && current_page !== undefined

const handlePrefetchPage = useCallback(
(page: number) => {
prefetchPagedMedia({
...params,
page,
})
},
[params],
)

// TODO: detect if going from page > 1 to page = 1 and scroll to top
useEffect(
() => {
Expand Down Expand Up @@ -106,7 +122,12 @@ function LibraryBooksScene() {

<div className="flex w-full flex-col gap-y-6">
{hasStuff && (
<Pagination pages={total_pages} currentPage={current_page} onChangePage={setPage} />
<Pagination
pages={total_pages}
currentPage={current_page}
onChangePage={setPage}
onPrefetchPage={handlePrefetchPage}
/>
)}
<div className="px-4">{renderContent()}</div>
{hasStuff && (
Expand All @@ -115,6 +136,7 @@ function LibraryBooksScene() {
pages={total_pages}
currentPage={current_page}
onChangePage={setPage}
onPrefetchPage={handlePrefetchPage}
/>
)}
</div>
Expand Down