Add trash and archive section, css fixups
This commit is contained in:
@ -27,6 +27,8 @@ export type NavigationSection =
|
||||
| 'library'
|
||||
| 'subscriptions'
|
||||
| 'highlights'
|
||||
| 'archive'
|
||||
| 'trash'
|
||||
|
||||
type NavigationLayoutProps = {
|
||||
children: ReactNode
|
||||
|
||||
@ -116,7 +116,7 @@ export function HomeFeedContainer(): JSX.Element {
|
||||
performActionOnItem,
|
||||
mutate,
|
||||
error: fetchItemsError,
|
||||
} = useGetLibraryItemsQuery(queryInputs)
|
||||
} = useGetLibraryItemsQuery('inbox', queryInputs)
|
||||
|
||||
useEffect(() => {
|
||||
const handleRevalidate = () => {
|
||||
|
||||
@ -73,7 +73,11 @@ const debouncedFetchSearchResults = debounce((query, cb) => {
|
||||
// the state as Failed. On refresh it will try again if the backend sends "PROCESSING"
|
||||
const TIMEOUT_DELAYS = [2000, 3500, 5000]
|
||||
|
||||
export function LibraryContainer(): JSX.Element {
|
||||
type LibraryContainerProps = {
|
||||
folder: string
|
||||
}
|
||||
|
||||
export function LibraryContainer(props: LibraryContainerProps): JSX.Element {
|
||||
const { viewerData } = useGetViewerQuery()
|
||||
const router = useRouter()
|
||||
const { queryValue } = useKBar((state) => ({ queryValue: state.searchQuery }))
|
||||
@ -81,6 +85,7 @@ export function LibraryContainer(): JSX.Element {
|
||||
|
||||
const defaultQuery = {
|
||||
limit: 10,
|
||||
folder: props.folder,
|
||||
sortDescending: true,
|
||||
searchQuery: undefined,
|
||||
}
|
||||
@ -111,7 +116,7 @@ export function LibraryContainer(): JSX.Element {
|
||||
performActionOnItem,
|
||||
mutate,
|
||||
error: fetchItemsError,
|
||||
} = useGetLibraryItemsQuery(queryInputs)
|
||||
} = useGetLibraryItemsQuery(props.folder, queryInputs)
|
||||
|
||||
useEffect(() => {
|
||||
const handleRevalidate = () => {
|
||||
@ -920,7 +925,7 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
|
||||
height: '100%',
|
||||
px: '20px',
|
||||
py: '20px',
|
||||
width: !showItems ? '100%' : 'unset',
|
||||
width: '100%',
|
||||
}}
|
||||
distribution="start"
|
||||
alignment="start"
|
||||
@ -1181,34 +1186,13 @@ function LibraryItems(props: LibraryItemsProps): JSX.Element {
|
||||
paddingBottom: '0px',
|
||||
overflow: 'visible',
|
||||
px: '70px',
|
||||
'@lgDown': {
|
||||
px: '10px',
|
||||
},
|
||||
gridTemplateColumns:
|
||||
props.layout == 'LIST_LAYOUT'
|
||||
? 'none'
|
||||
: `repeat( auto-fit, minmax(300px, 1fr) )`,
|
||||
// '@media (max-width: 930px)': {
|
||||
// gridGap: props.layout == 'LIST_LAYOUT' ? '0px' : '20px',
|
||||
// },
|
||||
// '@xlgDown': {
|
||||
// borderRadius: props.layout == 'LIST_LAYOUT' ? 0 : undefined,
|
||||
// },
|
||||
// '@smDown': {
|
||||
// border: 'unset',
|
||||
// width: props.layout == 'LIST_LAYOUT' ? '100vw' : undefined,
|
||||
// margin: props.layout == 'LIST_LAYOUT' ? '16px -16px' : undefined,
|
||||
// borderRadius: props.layout == 'LIST_LAYOUT' ? 0 : undefined,
|
||||
// },
|
||||
// '@media (min-width: 930px)': {
|
||||
// gridTemplateColumns:
|
||||
// props.layout == 'LIST_LAYOUT' ? 'none' : 'repeat(2, 1fr)',
|
||||
// },
|
||||
// '@media (min-width: 1280px)': {
|
||||
// gridTemplateColumns:
|
||||
// props.layout == 'LIST_LAYOUT' ? 'none' : 'repeat(3, 1fr)',
|
||||
// },
|
||||
// '@media (min-width: 1600px)': {
|
||||
// gridTemplateColumns:
|
||||
// props.layout == 'LIST_LAYOUT' ? 'none' : 'repeat(4, 1fr)',
|
||||
// },
|
||||
}}
|
||||
>
|
||||
{props.items.map((linkedItem) => (
|
||||
|
||||
@ -1,20 +1,12 @@
|
||||
import { Allotment } from 'allotment'
|
||||
import 'allotment/dist/style.css'
|
||||
import { useGetViewerQuery } from '../../../lib/networking/queries/useGetViewerQuery'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useKBar } from 'kbar'
|
||||
import { useState } from 'react'
|
||||
import { LibraryContainer } from './LibraryContainer'
|
||||
import { LibrarySideBar } from './LibrarySideBar'
|
||||
import { HighlightsList } from '../../../pages/highlights'
|
||||
|
||||
export function LibraryItemsContainer(): JSX.Element {
|
||||
const router = useRouter()
|
||||
|
||||
return (
|
||||
<Allotment>
|
||||
<Allotment.Pane minSize={200}>
|
||||
<LibraryContainer />
|
||||
<LibraryContainer folder="inbox" />
|
||||
</Allotment.Pane>
|
||||
{/* <Allotment.Pane snap maxSize={400}>
|
||||
<HighlightsList />
|
||||
|
||||
@ -2,7 +2,7 @@ import { ReactNode, useEffect, useMemo, useRef } from 'react'
|
||||
import { StyledText } from '../../elements/StyledText'
|
||||
import { Box, HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives'
|
||||
import { Button } from '../../elements/Button'
|
||||
import { Circle, NewspaperClipping, X } from '@phosphor-icons/react'
|
||||
import { Circle, X } from '@phosphor-icons/react'
|
||||
import {
|
||||
Subscription,
|
||||
SubscriptionType,
|
||||
|
||||
@ -46,55 +46,6 @@ type LibraryFilterMenuProps = {
|
||||
}
|
||||
|
||||
export function LibraryFilterMenu(props: LibraryFilterMenuProps): JSX.Element {
|
||||
const [labels, setLabels] = usePersistedState<Label[]>({
|
||||
key: 'menu-labels',
|
||||
isSessionStorage: false,
|
||||
initialValue: [],
|
||||
})
|
||||
const [savedSearches, setSavedSearches] = usePersistedState<SavedSearch[]>({
|
||||
key: 'menu-searches',
|
||||
isSessionStorage: false,
|
||||
initialValue: [],
|
||||
})
|
||||
const [subscriptions, setSubscriptions] = usePersistedState<Subscription[]>({
|
||||
key: 'menu-subscriptions',
|
||||
isSessionStorage: false,
|
||||
initialValue: [],
|
||||
})
|
||||
const labelsResponse = useGetLabelsQuery()
|
||||
const searchesResponse = useGetSavedSearchQuery()
|
||||
const subscriptionsResponse = useGetSubscriptionsQuery()
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!labelsResponse.error &&
|
||||
!labelsResponse.isLoading &&
|
||||
labelsResponse.labels
|
||||
) {
|
||||
setLabels(labelsResponse.labels)
|
||||
}
|
||||
}, [setLabels, labelsResponse])
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!subscriptionsResponse.error &&
|
||||
!subscriptionsResponse.isLoading &&
|
||||
subscriptionsResponse.subscriptions
|
||||
) {
|
||||
setSubscriptions(subscriptionsResponse.subscriptions)
|
||||
}
|
||||
}, [setSubscriptions, subscriptionsResponse])
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!searchesResponse.error &&
|
||||
!searchesResponse.isLoading &&
|
||||
searchesResponse.savedSearches
|
||||
) {
|
||||
setSavedSearches(searchesResponse.savedSearches)
|
||||
}
|
||||
}, [setSavedSearches, searchesResponse])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
|
||||
@ -17,17 +17,13 @@ import {
|
||||
Folder,
|
||||
FolderOpen,
|
||||
Tag,
|
||||
ArrowDown,
|
||||
CaretDown,
|
||||
CaretUp,
|
||||
} from '@phosphor-icons/react'
|
||||
import {
|
||||
Subscription,
|
||||
useGetSubscriptionsQuery,
|
||||
} from '../../../lib/networking/queries/useGetSubscriptionsQuery'
|
||||
import { useGetLabelsQuery } from '../../../lib/networking/queries/useGetLabelsQuery'
|
||||
import { Label } from '../../../lib/networking/fragments/labelFragment'
|
||||
import { theme } from '../../tokens/stitches.config'
|
||||
import { usePersistedState } from '../../../lib/hooks/usePersistedState'
|
||||
import { useGetSavedSearchQuery } from '../../../lib/networking/queries/useGetSavedSearchQuery'
|
||||
import { SavedSearch } from '../../../lib/networking/fragments/savedSearchFragment'
|
||||
import Link from 'next/link'
|
||||
import { NavMenuFooter } from './Footer'
|
||||
import { FollowingIcon } from '../../elements/icons/FollowingIcon'
|
||||
@ -49,6 +45,10 @@ import { requestHeaders } from '../../../lib/networking/networkHelpers'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { showErrorToast } from '../../../lib/toastHelpers'
|
||||
import { OpenMap } from 'react-arborist/dist/module/state/open-slice'
|
||||
import { ToggleCaretLeftIcon } from '../../elements/icons/ToggleCaretLeftIcon'
|
||||
import { ToggleCaretDownIcon } from '../../elements/icons/ToggleCaretDownIcon'
|
||||
import { TrashIcon } from '../../elements/icons/TrashIcon'
|
||||
import { ArchiveActionIcon } from '../../elements/icons/home/ArchiveActionIcon'
|
||||
|
||||
export const LIBRARY_LEFT_MENU_WIDTH = '275px'
|
||||
|
||||
@ -81,55 +81,6 @@ type LibraryFilterMenuProps = {
|
||||
}
|
||||
|
||||
export function NavigationMenu(props: LibraryFilterMenuProps): JSX.Element {
|
||||
const [labels, setLabels] = usePersistedState<Label[]>({
|
||||
key: 'menu-labels',
|
||||
isSessionStorage: false,
|
||||
initialValue: [],
|
||||
})
|
||||
const [savedSearches, setSavedSearches] = usePersistedState<SavedSearch[]>({
|
||||
key: 'menu-searches',
|
||||
isSessionStorage: false,
|
||||
initialValue: [],
|
||||
})
|
||||
const [subscriptions, setSubscriptions] = usePersistedState<Subscription[]>({
|
||||
key: 'menu-subscriptions',
|
||||
isSessionStorage: false,
|
||||
initialValue: [],
|
||||
})
|
||||
const labelsResponse = useGetLabelsQuery()
|
||||
const searchesResponse = useGetSavedSearchQuery()
|
||||
const subscriptionsResponse = useGetSubscriptionsQuery()
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!labelsResponse.error &&
|
||||
!labelsResponse.isLoading &&
|
||||
labelsResponse.labels
|
||||
) {
|
||||
setLabels(labelsResponse.labels)
|
||||
}
|
||||
}, [setLabels, labelsResponse])
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!subscriptionsResponse.error &&
|
||||
!subscriptionsResponse.isLoading &&
|
||||
subscriptionsResponse.subscriptions
|
||||
) {
|
||||
setSubscriptions(subscriptionsResponse.subscriptions)
|
||||
}
|
||||
}, [setSubscriptions, subscriptionsResponse])
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!searchesResponse.error &&
|
||||
!searchesResponse.isLoading &&
|
||||
searchesResponse.savedSearches
|
||||
) {
|
||||
setSavedSearches(searchesResponse.savedSearches)
|
||||
}
|
||||
}, [setSavedSearches, searchesResponse])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
@ -224,6 +175,12 @@ export function NavigationMenu(props: LibraryFilterMenuProps): JSX.Element {
|
||||
}
|
||||
|
||||
const LibraryNav = (props: LibraryFilterMenuProps): JSX.Element => {
|
||||
const [moreFoldersOpenState, setMoreFoldersOpenState] =
|
||||
usePersistedState<boolean>({
|
||||
key: 'nav-menu-more-folders-open',
|
||||
isSessionStorage: false,
|
||||
initialValue: false,
|
||||
})
|
||||
return (
|
||||
<VStack
|
||||
css={{
|
||||
@ -266,6 +223,48 @@ const LibraryNav = (props: LibraryFilterMenuProps): JSX.Element => {
|
||||
isSelected={props.section == 'highlights'}
|
||||
icon={<HighlightsIcon color={theme.colors.highlight.toString()} />}
|
||||
/>
|
||||
<Button
|
||||
style="articleActionIcon"
|
||||
css={{
|
||||
display: 'flex',
|
||||
ml: '15px',
|
||||
width: '100%',
|
||||
'&:hover': {
|
||||
backgroundColor: '$thBackground4',
|
||||
},
|
||||
}}
|
||||
onClick={(event) => {
|
||||
setMoreFoldersOpenState(!moreFoldersOpenState)
|
||||
event.preventDefault()
|
||||
}}
|
||||
>
|
||||
<HStack css={{ gap: '20px' }}>
|
||||
{moreFoldersOpenState ? (
|
||||
<CaretUp size={12} />
|
||||
) : (
|
||||
<CaretDown size={12} />
|
||||
)}
|
||||
<SpanBox>More</SpanBox>
|
||||
</HStack>
|
||||
</Button>
|
||||
{moreFoldersOpenState && (
|
||||
<SpanBox css={{ width: '100%' }}>
|
||||
<NavButton
|
||||
{...props}
|
||||
text="Archive"
|
||||
section="archive"
|
||||
isSelected={props.section == 'archive'}
|
||||
icon={<ArchiveActionIcon color="#F59932" />}
|
||||
/>
|
||||
<NavButton
|
||||
{...props}
|
||||
text="Trash"
|
||||
section="trash"
|
||||
isSelected={props.section == 'trash'}
|
||||
icon={<TrashIcon color={theme.colors.highlight.toString()} />}
|
||||
/>
|
||||
</SpanBox>
|
||||
)}
|
||||
</VStack>
|
||||
)
|
||||
}
|
||||
|
||||
@ -142,13 +142,11 @@ export const recommendationFragment = gql`
|
||||
}
|
||||
`
|
||||
|
||||
export function useGetLibraryItemsQuery({
|
||||
limit,
|
||||
sortDescending,
|
||||
searchQuery,
|
||||
cursor,
|
||||
includeContent = false,
|
||||
}: LibraryItemsQueryInput): LibraryItemsQueryResponse {
|
||||
export function useGetLibraryItemsQuery(
|
||||
folder: string,
|
||||
{ limit, searchQuery, cursor, includeContent = false }: LibraryItemsQueryInput
|
||||
): LibraryItemsQueryResponse {
|
||||
const fullQuery = (`in:${folder} use:folders ` + (searchQuery ?? '')).trim()
|
||||
const query = gql`
|
||||
query Search(
|
||||
$after: String
|
||||
@ -236,13 +234,13 @@ export function useGetLibraryItemsQuery({
|
||||
const variables = {
|
||||
after: cursor,
|
||||
first: limit,
|
||||
query: searchQuery,
|
||||
query: fullQuery,
|
||||
includeContent,
|
||||
}
|
||||
|
||||
const { data, error, mutate, size, setSize, isValidating } = useSWRInfinite(
|
||||
(pageIndex, previousPageData) => {
|
||||
const key = [query, limit, sortDescending, searchQuery, undefined]
|
||||
const key = [query, variables.first, variables.query, undefined]
|
||||
const previousResult = previousPageData as LibraryItemsData
|
||||
if (pageIndex === 0) {
|
||||
return key
|
||||
@ -250,7 +248,6 @@ export function useGetLibraryItemsQuery({
|
||||
return [
|
||||
query,
|
||||
limit,
|
||||
sortDescending,
|
||||
searchQuery,
|
||||
pageIndex === 0 ? undefined : previousResult.search.pageInfo.endCursor,
|
||||
]
|
||||
|
||||
16
packages/web/pages/archive/index.tsx
Normal file
16
packages/web/pages/archive/index.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { NavigationLayout } from '../../components/templates/NavigationLayout'
|
||||
import { LibraryContainer } from '../../components/templates/library/LibraryContainer'
|
||||
|
||||
export default function Archive(): JSX.Element {
|
||||
return (
|
||||
<NavigationLayout
|
||||
section="archive"
|
||||
pageMetaDataProps={{
|
||||
title: 'Archive',
|
||||
path: '/archive',
|
||||
}}
|
||||
>
|
||||
<LibraryContainer folder="archive" />
|
||||
</NavigationLayout>
|
||||
)
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
import { NavigationLayout } from '../../components/templates/NavigationLayout'
|
||||
import { Box } from '../../components/elements/LayoutPrimitives'
|
||||
import { LibraryContainer } from '../../components/templates/library/LibraryContainer'
|
||||
|
||||
export default function Library(): JSX.Element {
|
||||
@ -11,7 +10,7 @@ export default function Library(): JSX.Element {
|
||||
path: '/library',
|
||||
}}
|
||||
>
|
||||
<LibraryContainer />
|
||||
<LibraryContainer folder="inbox" />
|
||||
</NavigationLayout>
|
||||
)
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ export default function Account(): JSX.Element {
|
||||
isUsernameValidationLoading,
|
||||
])
|
||||
|
||||
const { itemsPages, isValidating } = useGetLibraryItemsQuery({
|
||||
const { itemsPages, isValidating } = useGetLibraryItemsQuery('', {
|
||||
limit: 0,
|
||||
searchQuery: 'in:all',
|
||||
sortDescending: false,
|
||||
|
||||
@ -1,7 +1,4 @@
|
||||
import { NavigationLayout } from '../../components/templates/NavigationLayout'
|
||||
import { PrimaryLayout } from '../../components/templates/PrimaryLayout'
|
||||
import { HomeFeedContainer } from '../../components/templates/homeFeed/HomeFeedContainer'
|
||||
import { Box, VStack } from '../../components/elements/LayoutPrimitives'
|
||||
import { LibraryContainer } from '../../components/templates/library/LibraryContainer'
|
||||
|
||||
export default function Subscriptions(): JSX.Element {
|
||||
@ -13,7 +10,7 @@ export default function Subscriptions(): JSX.Element {
|
||||
path: '/subscriptions',
|
||||
}}
|
||||
>
|
||||
<LibraryContainer />
|
||||
<LibraryContainer folder="following" />
|
||||
</NavigationLayout>
|
||||
)
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ export default function BulkPerformer(): JSX.Element {
|
||||
const [errorMessage, setErrorMessage] = useState<string | undefined>()
|
||||
const [runningState, setRunningState] = useState<RunningState>('none')
|
||||
|
||||
const { itemsPages, isValidating } = useGetLibraryItemsQuery({
|
||||
const { itemsPages, isValidating } = useGetLibraryItemsQuery('', {
|
||||
searchQuery: query,
|
||||
limit: 1,
|
||||
sortDescending: false,
|
||||
|
||||
16
packages/web/pages/trash/index.tsx
Normal file
16
packages/web/pages/trash/index.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { NavigationLayout } from '../../components/templates/NavigationLayout'
|
||||
import { LibraryContainer } from '../../components/templates/library/LibraryContainer'
|
||||
|
||||
export default function Trash(): JSX.Element {
|
||||
return (
|
||||
<NavigationLayout
|
||||
section="trash"
|
||||
pageMetaDataProps={{
|
||||
title: 'Trash',
|
||||
path: '/trash',
|
||||
}}
|
||||
>
|
||||
<LibraryContainer folder="trash" />
|
||||
</NavigationLayout>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user