mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Add some legacy support for the mobile view items, we will slowly remove these
This commit is contained in:
parent
4dfee8d7f7
commit
b8a42439d7
3 changed files with 332 additions and 196 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { Box, HStack, VStack } from './../../elements/LayoutPrimitives'
|
||||
import { Box, HStack, SpanBox, VStack } from './../../elements/LayoutPrimitives'
|
||||
import Dropzone from 'react-dropzone'
|
||||
import * as Progress from '@radix-ui/react-progress'
|
||||
import type {
|
||||
|
|
@ -6,7 +6,10 @@ import type {
|
|||
LibraryItemsQueryInput,
|
||||
} from '../../../lib/networking/queries/useGetLibraryItemsQuery'
|
||||
import { useGetLibraryItemsQuery } from '../../../lib/networking/queries/useGetLibraryItemsQuery'
|
||||
import { useGetViewerQuery } from '../../../lib/networking/queries/useGetViewerQuery'
|
||||
import {
|
||||
useGetViewerQuery,
|
||||
UserBasicData,
|
||||
} from '../../../lib/networking/queries/useGetViewerQuery'
|
||||
import { LinkedItemCardAction } from '../../patterns/LibraryCards/CardTypes'
|
||||
import { LinkedItemCard } from '../../patterns/LibraryCards/LinkedItemCard'
|
||||
import { useRouter } from 'next/router'
|
||||
|
|
@ -679,25 +682,6 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
|
|||
|
||||
const [, updateState] = useState({})
|
||||
|
||||
const StyledToggleButton = styled('button', {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
p: '0px',
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
borderRadius: '4px',
|
||||
'&:hover': {
|
||||
opacity: 0.8,
|
||||
},
|
||||
'&[data-state="on"]': {
|
||||
bg: 'rgb(43, 43, 43)',
|
||||
},
|
||||
})
|
||||
|
||||
const DragnDropContainer = styled('div', {
|
||||
width: '100%',
|
||||
height: '80%',
|
||||
|
|
@ -800,22 +784,16 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
|
|||
searchTerm={props.searchTerm}
|
||||
applySearchQuery={props.applySearchQuery}
|
||||
/>
|
||||
<Box
|
||||
css={{
|
||||
height: '105px',
|
||||
bg: '$grayBase',
|
||||
}}
|
||||
></Box>
|
||||
<HStack css={{ width: '100%', height: '100%' }}>
|
||||
<LibraryFilterMenu />
|
||||
<Box
|
||||
<SpanBox
|
||||
css={{
|
||||
width: '233px',
|
||||
minWidth: '233px',
|
||||
height: '100%',
|
||||
bg: '$grayBase',
|
||||
'@mdDown': {
|
||||
display: 'none',
|
||||
},
|
||||
}}
|
||||
></Box>
|
||||
>
|
||||
<LibraryFilterMenu />
|
||||
</SpanBox>
|
||||
|
||||
<VStack
|
||||
alignment="center"
|
||||
|
|
@ -830,104 +808,25 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
|
|||
<Toaster />
|
||||
|
||||
{props.isValidating && props.items.length == 0 && <TopBarProgress />}
|
||||
{/* <HStack alignment="center" distribution="start" css={{ width: '100%' }}>
|
||||
<StyledText
|
||||
style="subHeadline"
|
||||
|
||||
<SpanBox
|
||||
css={{
|
||||
mr: '32px',
|
||||
'@smDown': {
|
||||
mr: '16px',
|
||||
width: '100%',
|
||||
'@md': {
|
||||
display: 'none',
|
||||
},
|
||||
}}
|
||||
>
|
||||
Library
|
||||
</StyledText>
|
||||
<Box
|
||||
css={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<StyledToggleButton
|
||||
data-state={layout === 'GRID_LAYOUT' ? 'on' : 'off'}
|
||||
onClick={() => {
|
||||
updateLayout('GRID_LAYOUT')
|
||||
}}
|
||||
>
|
||||
<GridLayoutIcon color={'rgb(211, 211, 213)'} />
|
||||
</StyledToggleButton>
|
||||
<StyledToggleButton
|
||||
data-state={layout === 'LIST_LAYOUT' ? 'on' : 'off'}
|
||||
onClick={() => {
|
||||
updateLayout('LIST_LAYOUT')
|
||||
}}
|
||||
>
|
||||
<ListLayoutIcon color={'rgb(211, 211, 213)'} />
|
||||
</StyledToggleButton>
|
||||
</Box>
|
||||
<Button
|
||||
style="ctaDarkYellow"
|
||||
css={{ marginLeft: 'auto' }}
|
||||
onClick={() => {
|
||||
props.setShowAddLinkModal(true)
|
||||
}}
|
||||
>
|
||||
Add Link
|
||||
</Button>
|
||||
</HStack>
|
||||
<LibrarySearchBar
|
||||
searchTerm={props.searchTerm}
|
||||
applySearchQuery={props.applySearchQuery}
|
||||
/> */}
|
||||
<LegacyMobileTopNav
|
||||
viewer={viewerData?.me}
|
||||
searchTerm={props.searchTerm}
|
||||
applySearchQuery={props.applySearchQuery}
|
||||
layout={layout}
|
||||
updateLayout={updateLayout}
|
||||
setShowAddLinkModal={props.setShowAddLinkModal}
|
||||
/>
|
||||
</SpanBox>
|
||||
|
||||
{/* {viewerData?.me && (
|
||||
<Box
|
||||
css={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
height: '44px',
|
||||
marginTop: '16px',
|
||||
gap: '8px',
|
||||
flexDirection: 'row',
|
||||
overflowY: 'scroll',
|
||||
scrollbarWidth: 'none',
|
||||
'&::-webkit-scrollbar': {
|
||||
display: 'none',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{Object.keys(SAVED_SEARCHES).map((key) => {
|
||||
const isInboxTerm = (term: string) => {
|
||||
return !term || term === 'in:inbox'
|
||||
}
|
||||
|
||||
const searchQuery = SAVED_SEARCHES[key]
|
||||
const style =
|
||||
searchQuery === props.searchTerm ||
|
||||
(!props.searchTerm && isInboxTerm(searchQuery))
|
||||
? 'ctaDarkYellow'
|
||||
: 'ctaLightGray'
|
||||
return (
|
||||
<Button
|
||||
key={key}
|
||||
style={style}
|
||||
onClick={() => {
|
||||
props.applySearchQuery(searchQuery)
|
||||
}}
|
||||
css={{
|
||||
p: '10px 12px',
|
||||
height: '37.5px',
|
||||
borderRadius: '6px',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{key}
|
||||
</Button>
|
||||
)
|
||||
})}
|
||||
</Box>
|
||||
)} */}
|
||||
<Dropzone
|
||||
onDrop={handleDrop}
|
||||
onDragEnter={() => {
|
||||
|
|
@ -1263,3 +1162,142 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
|
|||
</VStack>
|
||||
)
|
||||
}
|
||||
|
||||
type LegacyMobileTopNavProps = {
|
||||
viewer?: UserBasicData
|
||||
searchTerm?: string
|
||||
applySearchQuery: (searchQuery: string) => void
|
||||
|
||||
layout: LayoutType
|
||||
updateLayout: (layout: LayoutType) => void
|
||||
|
||||
setShowAddLinkModal: (show: boolean) => void
|
||||
}
|
||||
|
||||
function LegacyMobileTopNav(props: LegacyMobileTopNavProps): JSX.Element {
|
||||
const StyledToggleButton = styled('button', {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
p: '0px',
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
borderRadius: '4px',
|
||||
'&:hover': {
|
||||
opacity: 0.8,
|
||||
},
|
||||
'&[data-state="on"]': {
|
||||
bg: 'rgb(43, 43, 43)',
|
||||
},
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<HStack
|
||||
alignment="center"
|
||||
distribution="start"
|
||||
css={{ width: '100%', '@md': { display: 'none' } }}
|
||||
>
|
||||
<StyledText
|
||||
style="subHeadline"
|
||||
css={{
|
||||
mr: '32px',
|
||||
'@smDown': {
|
||||
mr: '16px',
|
||||
},
|
||||
}}
|
||||
>
|
||||
Library
|
||||
</StyledText>
|
||||
<Box
|
||||
css={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<StyledToggleButton
|
||||
data-state={props.layout === 'GRID_LAYOUT' ? 'on' : 'off'}
|
||||
onClick={() => {
|
||||
props.updateLayout('GRID_LAYOUT')
|
||||
}}
|
||||
>
|
||||
<GridLayoutIcon color={'rgb(211, 211, 213)'} />
|
||||
</StyledToggleButton>
|
||||
<StyledToggleButton
|
||||
data-state={props.layout === 'LIST_LAYOUT' ? 'on' : 'off'}
|
||||
onClick={() => {
|
||||
props.updateLayout('LIST_LAYOUT')
|
||||
}}
|
||||
>
|
||||
<ListLayoutIcon color={'rgb(211, 211, 213)'} />
|
||||
</StyledToggleButton>
|
||||
</Box>
|
||||
<Button
|
||||
style="ctaDarkYellow"
|
||||
css={{ marginLeft: 'auto' }}
|
||||
onClick={() => {
|
||||
props.setShowAddLinkModal(true)
|
||||
}}
|
||||
>
|
||||
Add Link
|
||||
</Button>
|
||||
</HStack>
|
||||
<LibrarySearchBar
|
||||
searchTerm={props.searchTerm}
|
||||
applySearchQuery={props.applySearchQuery}
|
||||
/>
|
||||
|
||||
{props.viewer && (
|
||||
<Box
|
||||
css={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
height: '44px',
|
||||
marginTop: '16px',
|
||||
gap: '8px',
|
||||
flexDirection: 'row',
|
||||
overflowY: 'scroll',
|
||||
scrollbarWidth: 'none',
|
||||
'&::-webkit-scrollbar': {
|
||||
display: 'none',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{Object.keys(SAVED_SEARCHES).map((key) => {
|
||||
const isInboxTerm = (term: string) => {
|
||||
return !term || term === 'in:inbox'
|
||||
}
|
||||
|
||||
const searchQuery = SAVED_SEARCHES[key]
|
||||
const style =
|
||||
searchQuery === props.searchTerm ||
|
||||
(!props.searchTerm && isInboxTerm(searchQuery))
|
||||
? 'ctaDarkYellow'
|
||||
: 'ctaLightGray'
|
||||
return (
|
||||
<Button
|
||||
key={key}
|
||||
style={style}
|
||||
onClick={() => {
|
||||
props.applySearchQuery(searchQuery)
|
||||
}}
|
||||
css={{
|
||||
p: '10px 12px',
|
||||
height: '37.5px',
|
||||
borderRadius: '6px',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{key}
|
||||
</Button>
|
||||
)
|
||||
})}
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,14 @@ import { FormInput } from '../../elements/FormElements'
|
|||
import { searchBarCommands } from '../../../lib/keyboardShortcuts/navigationShortcuts'
|
||||
import { useKeyboardShortcuts } from '../../../lib/keyboardShortcuts/useKeyboardShortcuts'
|
||||
import { Button, IconButton } from '../../elements/Button'
|
||||
import { Circle, MagnifyingGlass, Plus, Textbox, X } from 'phosphor-react'
|
||||
import {
|
||||
Circle,
|
||||
DotsThree,
|
||||
MagnifyingGlass,
|
||||
Plus,
|
||||
Textbox,
|
||||
X,
|
||||
} from 'phosphor-react'
|
||||
import { OmnivoreNameLogo } from '../../elements/images/OmnivoreNameLogo'
|
||||
import { OmnivoreFullLogo } from '../../elements/images/OmnivoreFullLogo'
|
||||
import { AvatarDropdown } from '../../elements/AvatarDropdown'
|
||||
|
|
@ -27,24 +34,36 @@ import { Checkbox } from '@radix-ui/react-checkbox'
|
|||
|
||||
export function LibraryFilterMenu(): JSX.Element {
|
||||
return (
|
||||
<Box
|
||||
css={{
|
||||
left: '0px',
|
||||
top: '105px',
|
||||
position: 'fixed',
|
||||
bg: 'white',
|
||||
width: '233px',
|
||||
height: '100%',
|
||||
borderRight: '1px solid #E1E1E1',
|
||||
pr: '15px',
|
||||
}}
|
||||
>
|
||||
<SavedSearches />
|
||||
<Subscriptions />
|
||||
<Labels />
|
||||
<>
|
||||
<Box
|
||||
css={{
|
||||
left: '0px',
|
||||
top: '105px',
|
||||
position: 'fixed',
|
||||
bg: 'white',
|
||||
width: '233px',
|
||||
height: '100%',
|
||||
borderRight: '1px solid #E1E1E1',
|
||||
pr: '15px',
|
||||
}}
|
||||
>
|
||||
<SavedSearches />
|
||||
<Subscriptions />
|
||||
<Labels />
|
||||
|
||||
<AddLinkButton />
|
||||
</Box>
|
||||
<AddLinkButton />
|
||||
</Box>
|
||||
{/* This spacer pushes library content to the right of
|
||||
the fixed left side menu. */}
|
||||
<Box
|
||||
css={{
|
||||
width: '233px',
|
||||
minWidth: '233px',
|
||||
height: '100%',
|
||||
bg: '$grayBase',
|
||||
}}
|
||||
></Box>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -62,32 +81,40 @@ function SavedSearches(): JSX.Element {
|
|||
|
||||
function Subscriptions(): JSX.Element {
|
||||
const { subscriptions } = useGetSubscriptionsQuery()
|
||||
console.log('subscriptions: ', subscriptions)
|
||||
const [viewAll, setViewAll] = useState(false)
|
||||
|
||||
return (
|
||||
<MenuPanel title="Subscriptions">
|
||||
{subscriptions.slice(0, 4).map((item) => {
|
||||
<MenuPanel
|
||||
title="Subscriptions"
|
||||
editTitle="Edit Subscriptions"
|
||||
editFunc={() => {
|
||||
window.location.href = '/settings/subscriptions'
|
||||
}}
|
||||
>
|
||||
{subscriptions.slice(0, viewAll ? undefined : 4).map((item) => {
|
||||
return <FilterButton key={item.id} text={item.name} selected={false} />
|
||||
})}
|
||||
<StyledText css={{ pl: '10px', color: '#BEBEBE', fontWeight: '600' }}>
|
||||
View All
|
||||
</StyledText>
|
||||
<ViewAllButton state={viewAll} setState={setViewAll} />
|
||||
</MenuPanel>
|
||||
)
|
||||
}
|
||||
|
||||
function Labels(): JSX.Element {
|
||||
const { labels } = useGetLabelsQuery()
|
||||
console.log('labels: ', labels)
|
||||
const [viewAll, setViewAll] = useState(false)
|
||||
|
||||
return (
|
||||
<MenuPanel title="Labels">
|
||||
{labels.slice(0, 4).map((item) => {
|
||||
<MenuPanel
|
||||
title="Labels"
|
||||
editTitle="Edit Labels"
|
||||
editFunc={() => {
|
||||
window.location.href = '/settings/labels'
|
||||
}}
|
||||
>
|
||||
{labels.slice(0, viewAll ? undefined : 4).map((item) => {
|
||||
return <LabelButton key={item.id} label={item} state="off" />
|
||||
})}
|
||||
<StyledText css={{ pl: '10px', color: '#BEBEBE', fontWeight: '600' }}>
|
||||
View All
|
||||
</StyledText>
|
||||
<ViewAllButton state={viewAll} setState={setViewAll} />
|
||||
</MenuPanel>
|
||||
)
|
||||
}
|
||||
|
|
@ -95,6 +122,8 @@ function Labels(): JSX.Element {
|
|||
type MenuPanelProps = {
|
||||
title: string
|
||||
children: ReactNode
|
||||
editFunc?: () => void
|
||||
editTitle?: string
|
||||
}
|
||||
|
||||
function MenuPanel(props: MenuPanelProps): JSX.Element {
|
||||
|
|
@ -108,19 +137,46 @@ function MenuPanel(props: MenuPanelProps): JSX.Element {
|
|||
alignment="start"
|
||||
distribution="start"
|
||||
>
|
||||
<StyledText
|
||||
css={{
|
||||
fontFamily: 'Inter',
|
||||
fontWeight: '600',
|
||||
fontSize: '16px',
|
||||
lineHeight: '125%',
|
||||
color: '#1E1E1E',
|
||||
pl: '10px',
|
||||
my: '20px',
|
||||
}}
|
||||
>
|
||||
{props.title}
|
||||
</StyledText>
|
||||
<HStack css={{ width: '100%' }} distribution="start" alignment="start">
|
||||
<StyledText
|
||||
css={{
|
||||
fontFamily: 'Inter',
|
||||
fontWeight: '600',
|
||||
fontSize: '16px',
|
||||
lineHeight: '125%',
|
||||
color: '#1E1E1E',
|
||||
pl: '10px',
|
||||
my: '20px',
|
||||
}}
|
||||
>
|
||||
{props.title}
|
||||
</StyledText>
|
||||
<SpanBox
|
||||
css={{
|
||||
my: '15px',
|
||||
marginLeft: 'auto',
|
||||
height: '100%',
|
||||
verticalAlign: 'middle',
|
||||
}}
|
||||
>
|
||||
{props.editTitle && props.editFunc && (
|
||||
<Dropdown
|
||||
triggerElement={
|
||||
<DotsThree width={20} weight="bold" color="#BEBEBE" />
|
||||
}
|
||||
>
|
||||
<DropdownOption
|
||||
title={props.editTitle}
|
||||
onSelect={() => {
|
||||
if (props.editFunc) {
|
||||
props.editFunc()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Dropdown>
|
||||
)}
|
||||
</SpanBox>
|
||||
</HStack>
|
||||
{props.children}
|
||||
</VStack>
|
||||
)
|
||||
|
|
@ -217,3 +273,29 @@ function AddLinkButton(): JSX.Element {
|
|||
</VStack>
|
||||
)
|
||||
}
|
||||
|
||||
type ViewAllButtonProps = {
|
||||
state: boolean
|
||||
setState: (state: boolean) => void
|
||||
}
|
||||
|
||||
function ViewAllButton(props: ViewAllButtonProps): JSX.Element {
|
||||
return (
|
||||
<Button
|
||||
style="ghost"
|
||||
css={{
|
||||
pl: '10px',
|
||||
color: '#BEBEBE',
|
||||
fontWeight: '600',
|
||||
fontSize: '12px',
|
||||
py: '20px',
|
||||
}}
|
||||
onClick={(e) => {
|
||||
props.setState(!props.state)
|
||||
e.preventDefault()
|
||||
}}
|
||||
>
|
||||
{props.state ? 'Hide' : 'View All'}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,9 @@ const recentlySavedStartDate = new Date(
|
|||
|
||||
const FOCUSED_BOXSHADOW = '0px 0px 2px 2px rgba(255, 234, 159, 0.56)'
|
||||
|
||||
const HEADER_HEIGHT = '105px'
|
||||
const MOBILE_HEIGHT = '44px'
|
||||
|
||||
export function LibraryHeader(props: LibrarySearchBarProps): JSX.Element {
|
||||
const [focused, setFocused] = useState(false)
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
|
|
@ -60,38 +63,51 @@ export function LibraryHeader(props: LibrarySearchBarProps): JSX.Element {
|
|||
)
|
||||
|
||||
return (
|
||||
<VStack
|
||||
alignment="center"
|
||||
distribution="start"
|
||||
css={{
|
||||
top: '0',
|
||||
left: '0',
|
||||
zIndex: 100,
|
||||
position: 'fixed',
|
||||
width: '100%',
|
||||
height: '105px',
|
||||
bg: 'white',
|
||||
pt: '50px',
|
||||
borderBottom: '1px solid #E1E1E1',
|
||||
'@mdDown': {
|
||||
height: '40px',
|
||||
pt: '0px',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<HStack
|
||||
<>
|
||||
<VStack
|
||||
alignment="center"
|
||||
distribution="start"
|
||||
css={{
|
||||
top: '0',
|
||||
left: '0',
|
||||
zIndex: 100,
|
||||
position: 'fixed',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
height: HEADER_HEIGHT,
|
||||
bg: 'white',
|
||||
pt: '35px',
|
||||
borderBottom: '1px solid #E1E1E1',
|
||||
'@mdDown': {
|
||||
height: MOBILE_HEIGHT,
|
||||
pt: '0px',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<LogoBox />
|
||||
<SearchBox {...props} />
|
||||
<ControlButtonBox />
|
||||
</HStack>
|
||||
</VStack>
|
||||
<HStack
|
||||
alignment="center"
|
||||
distribution="start"
|
||||
css={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}}
|
||||
>
|
||||
<LogoBox />
|
||||
<SearchBox {...props} />
|
||||
<ControlButtonBox />
|
||||
</HStack>
|
||||
</VStack>
|
||||
{/* This spacer is put in to push library content down
|
||||
below the fixed header height. */}
|
||||
<Box
|
||||
css={{
|
||||
height: HEADER_HEIGHT,
|
||||
bg: '$grayBase',
|
||||
'@mdDown': {
|
||||
height: MOBILE_HEIGHT,
|
||||
},
|
||||
}}
|
||||
></Box>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue