Merge pull request #4058 from omnivore-app/feat/web-home-float
Use a float for the thumbnail to improve text layout
This commit is contained in:
@ -47,6 +47,7 @@ export function HomeContainer(): JSX.Element {
|
||||
bg: '$readerBg',
|
||||
pt: '45px',
|
||||
minHeight: '100vh',
|
||||
minWidth: '320px',
|
||||
}}
|
||||
>
|
||||
<Toaster />
|
||||
@ -120,6 +121,7 @@ const JustAddedHomeSection = (props: HomeSectionProps): JSX.Element => {
|
||||
distribution="start"
|
||||
css={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
gap: '20px',
|
||||
}}
|
||||
>
|
||||
@ -172,8 +174,9 @@ const JustAddedHomeSection = (props: HomeSectionProps): JSX.Element => {
|
||||
<HStack
|
||||
css={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
lineHeight: '1',
|
||||
overflow: 'scroll',
|
||||
overflowX: 'scroll',
|
||||
gap: '25px',
|
||||
scrollbarWidth: 'none',
|
||||
'::-webkit-scrollbar': {
|
||||
@ -366,6 +369,7 @@ const TimeAgo = (props: HomeItemViewProps): JSX.Element => {
|
||||
fontWeight: 'medium',
|
||||
fontFamily: '$inter',
|
||||
color: '$homeTextSubtle',
|
||||
flexShrink: '0',
|
||||
}}
|
||||
>
|
||||
{timeAgo(props.homeItem.date)}
|
||||
@ -380,6 +384,7 @@ const Title = (props: HomeItemViewProps): JSX.Element => {
|
||||
distribution="start"
|
||||
alignment="center"
|
||||
css={{
|
||||
mb: '6px',
|
||||
fontSize: '18px',
|
||||
lineHeight: '24px',
|
||||
fontWeight: '600',
|
||||
@ -414,6 +419,7 @@ const TitleSmall = (props: HomeItemViewProps): JSX.Element => {
|
||||
css={{
|
||||
fontSize: '14px',
|
||||
lineHeight: '21px',
|
||||
minHeight: '42px', // always have two lines of space
|
||||
fontWeight: '500',
|
||||
fontFamily: '$inter',
|
||||
color: '$homeTextTitle',
|
||||
@ -495,7 +501,7 @@ const JustAddedItemView = (props: HomeItemViewProps): JSX.Element => {
|
||||
css={{ width: '100%', gap: '5px', lineHeight: '1' }}
|
||||
>
|
||||
<SourceInfo homeItem={props.homeItem} subtle={true} />
|
||||
<SpanBox css={{ ml: 'auto' }}>
|
||||
<SpanBox css={{ ml: 'auto', flexShrink: '0' }}>
|
||||
<TimeAgo homeItem={props.homeItem} />
|
||||
</SpanBox>
|
||||
</HStack>
|
||||
@ -513,7 +519,7 @@ const TopicPickHomeItemView = (props: HomeItemViewProps): JSX.Element => {
|
||||
css={{
|
||||
width: '100%',
|
||||
p: '0px',
|
||||
pt: '35px',
|
||||
pt: '20px',
|
||||
cursor: 'pointer',
|
||||
borderRadius: '5px',
|
||||
'@mdDown': {
|
||||
@ -537,38 +543,37 @@ const TopicPickHomeItemView = (props: HomeItemViewProps): JSX.Element => {
|
||||
}}
|
||||
alignment="start"
|
||||
>
|
||||
<HStack css={{ width: '100%', gap: '5px', px: '20px' }}>
|
||||
<VStack css={{ gap: '15px' }}>
|
||||
<HStack
|
||||
distribution="start"
|
||||
alignment="center"
|
||||
css={{ gap: '5px', lineHeight: '1' }}
|
||||
>
|
||||
<SourceInfo homeItem={props.homeItem} />
|
||||
<Box css={{ width: '100%', gap: '10px', px: '20px' }}>
|
||||
<HStack
|
||||
distribution="start"
|
||||
alignment="center"
|
||||
css={{ gap: '5px', lineHeight: '1', mb: '10px' }}
|
||||
>
|
||||
<SourceInfo homeItem={props.homeItem} />
|
||||
<SpanBox css={{ '@mdDown': { ml: 'auto' } }}>
|
||||
<TimeAgo homeItem={props.homeItem} />
|
||||
</HStack>
|
||||
<Title homeItem={props.homeItem} />
|
||||
</VStack>
|
||||
<SpanBox css={{ ml: 'auto' }}>
|
||||
{props.homeItem.thumbnail && (
|
||||
<CoverImage
|
||||
css={{
|
||||
mt: '6px',
|
||||
width: '120px',
|
||||
height: '70px',
|
||||
borderRadius: '4px',
|
||||
}}
|
||||
src={props.homeItem.thumbnail}
|
||||
></CoverImage>
|
||||
)}
|
||||
</SpanBox>
|
||||
</HStack>
|
||||
<SpanBox css={{ px: '20px' }}>
|
||||
</SpanBox>
|
||||
</HStack>
|
||||
|
||||
{props.homeItem.thumbnail && (
|
||||
<CoverImage
|
||||
css={{
|
||||
width: '120px',
|
||||
height: '70px',
|
||||
borderRadius: '4px',
|
||||
marginLeft: '10px',
|
||||
float: 'right',
|
||||
}}
|
||||
src={props.homeItem.thumbnail}
|
||||
></CoverImage>
|
||||
)}
|
||||
<Title homeItem={props.homeItem} />
|
||||
<PreviewContent
|
||||
previewContent={props.homeItem.previewContent}
|
||||
maxLines="6"
|
||||
/>
|
||||
</SpanBox>
|
||||
</Box>
|
||||
<SpanBox css={{ px: '20px' }}></SpanBox>
|
||||
<HStack css={{ gap: '10px', my: '15px', px: '20px' }}>
|
||||
<Button style="homeAction">
|
||||
<AddToLibraryActionIcon
|
||||
@ -608,6 +613,7 @@ const QuickLinkHomeItemView = (props: HomeItemViewProps): JSX.Element => {
|
||||
gap: '5px',
|
||||
borderRadius: '5px',
|
||||
'&:hover': {
|
||||
bg: '#007AFF10',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
'&:hover .title-text': {
|
||||
@ -630,7 +636,7 @@ const QuickLinkHomeItemView = (props: HomeItemViewProps): JSX.Element => {
|
||||
>
|
||||
<SourceInfo homeItem={props.homeItem} subtle={true} />
|
||||
|
||||
<SpanBox css={{ ml: 'auto' }}>
|
||||
<SpanBox css={{ ml: 'auto', flexShrink: '0' }}>
|
||||
<TimeAgo homeItem={props.homeItem} />
|
||||
</SpanBox>
|
||||
</HStack>
|
||||
@ -665,7 +671,14 @@ const SourceInfo = (props: HomeItemViewProps & SourceInfoProps) => (
|
||||
<HStack
|
||||
distribution="start"
|
||||
alignment="center"
|
||||
css={{ gap: '8px', cursor: 'pointer' }}
|
||||
css={{
|
||||
gap: '8px',
|
||||
cursor: 'pointer',
|
||||
flex: '1',
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
}}
|
||||
>
|
||||
{props.homeItem.source.icon && (
|
||||
<SiteIconSmall
|
||||
|
||||
@ -67,12 +67,12 @@ export function LibraryGridCard(props: LinkedItemCardProps): JSX.Element {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
minHeight: '270px',
|
||||
background: 'white',
|
||||
borderRadius: '5px',
|
||||
borderWidth: '1px',
|
||||
borderStyle: 'none',
|
||||
overflow: 'hidden',
|
||||
cursor: 'pointer',
|
||||
border: props.legacyLayout ? 'unset' : '1px solid black',
|
||||
'@media (max-width: 930px)': {
|
||||
width: 'calc(100% - 30px)',
|
||||
},
|
||||
|
||||
@ -44,7 +44,7 @@ export function NavigationLayout(props: NavigationLayoutProps): JSX.Element {
|
||||
const [showKeyboardCommandsModal, setShowKeyboardCommandsModal] =
|
||||
useState(false)
|
||||
|
||||
const [showNavMenu, setShowNavMenu] = usePersistedState<boolean>({
|
||||
const [showNavMenu, setShowNavMenu, isLoading] = usePersistedState<boolean>({
|
||||
key: 'nav-show-menu',
|
||||
isSessionStorage: false,
|
||||
initialValue: true,
|
||||
@ -111,6 +111,16 @@ export function NavigationLayout(props: NavigationLayoutProps): JSX.Element {
|
||||
}
|
||||
}, [showLogout])
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<HStack
|
||||
css={{ width: '100vw', height: '100vh' }}
|
||||
distribution="start"
|
||||
alignment="start"
|
||||
></HStack>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<HStack
|
||||
css={{ width: '100vw', height: '100vh' }}
|
||||
@ -133,7 +143,7 @@ export function NavigationLayout(props: NavigationLayoutProps): JSX.Element {
|
||||
}}
|
||||
/>
|
||||
</SpanBox>
|
||||
{showNavMenu && (
|
||||
{!isLoading && showNavMenu && (
|
||||
<NavigationMenu
|
||||
section={props.section}
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
|
||||
@ -35,8 +35,9 @@ export default function PdfArticleContainer(
|
||||
const containerRef = useRef<HTMLDivElement | null>(null)
|
||||
const [notebookKey, setNotebookKey] = useState<string>(uuidv4())
|
||||
const [noteTarget, setNoteTarget] = useState<Highlight | undefined>(undefined)
|
||||
const [noteTargetPageIndex, setNoteTargetPageIndex] =
|
||||
useState<number | undefined>(undefined)
|
||||
const [noteTargetPageIndex, setNoteTargetPageIndex] = useState<
|
||||
number | undefined
|
||||
>(undefined)
|
||||
const highlightsRef = useRef<Highlight[]>([])
|
||||
|
||||
const annotationOmnivoreId = (annotation: Annotation): string | undefined => {
|
||||
@ -448,6 +449,11 @@ export default function PdfArticleContainer(
|
||||
document.dispatchEvent(new Event('openOriginalArticle'))
|
||||
break
|
||||
case 'u':
|
||||
const navReturn = window.sessionStorage.getItem('nav-return')
|
||||
if (navReturn) {
|
||||
window.location.assign(navReturn)
|
||||
return
|
||||
}
|
||||
const query = window.sessionStorage.getItem('q')
|
||||
if (query) {
|
||||
window.location.assign(`/home?${query}`)
|
||||
|
||||
@ -1040,7 +1040,12 @@ export function LibraryItemsLayout(
|
||||
'@lgDown': {
|
||||
display: 'none',
|
||||
},
|
||||
mt: '10px',
|
||||
mb: '10px',
|
||||
px: '70px',
|
||||
'@xlgDown': {
|
||||
px: '10px',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<PinnedButtons
|
||||
@ -1189,7 +1194,7 @@ function LibraryItems(props: LibraryItemsProps): JSX.Element {
|
||||
paddingBottom: '0px',
|
||||
overflow: 'visible',
|
||||
px: '70px',
|
||||
'@lgDown': {
|
||||
'@xlgDown': {
|
||||
px: '10px',
|
||||
},
|
||||
'@mdDown': {
|
||||
@ -1199,7 +1204,7 @@ function LibraryItems(props: LibraryItemsProps): JSX.Element {
|
||||
gridTemplateColumns:
|
||||
props.layout == 'LIST_LAYOUT'
|
||||
? 'none'
|
||||
: `repeat( auto-fit, minmax(300px, 1fr) )`,
|
||||
: `repeat( auto-fit, minmax(280px, 1fr) )`,
|
||||
}}
|
||||
>
|
||||
{props.items.map((linkedItem) => (
|
||||
@ -1215,7 +1220,7 @@ function LibraryItems(props: LibraryItemsProps): JSX.Element {
|
||||
outline: 'none',
|
||||
},
|
||||
'&> div': {
|
||||
bg: '$thLeftMenuBackground',
|
||||
// bg: '$thLeftMenuBackground',
|
||||
// bg: '$thLibraryBackground',
|
||||
},
|
||||
'&:focus': {
|
||||
|
||||
@ -88,7 +88,9 @@ export function LibraryHeader(props: LibraryHeaderProps): JSX.Element {
|
||||
px: '70px',
|
||||
left: LIBRARY_LEFT_MENU_WIDTH,
|
||||
transition: 'height 0.5s',
|
||||
'@lgDown': { px: '20px' },
|
||||
'@xlgDown': {
|
||||
px: '10px',
|
||||
},
|
||||
'@mdDown': {
|
||||
px: '10px',
|
||||
left: '0px',
|
||||
@ -272,7 +274,7 @@ export function SearchBox(props: SearchBoxProps): JSX.Element {
|
||||
height: '38px',
|
||||
width: '100%',
|
||||
maxWidth: '521px',
|
||||
bg: '$thLibrarySearchbox',
|
||||
bg: '$backgroundMedium',
|
||||
borderRadius: '6px',
|
||||
boxShadow: props.searchBoxFocused
|
||||
? 'none'
|
||||
|
||||
@ -24,9 +24,6 @@ export const NavMenuFooter = (props: NavMenuFooterProps): JSX.Element => {
|
||||
'&::-webkit-scrollbar': {
|
||||
display: 'none',
|
||||
},
|
||||
'@mdDown': {
|
||||
width: '100%',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<PrimaryDropdown />
|
||||
|
||||
@ -85,10 +85,11 @@ export function NavigationMenu(props: NavigationMenuProps): JSX.Element {
|
||||
display: 'none',
|
||||
},
|
||||
'@mdDown': {
|
||||
width: '100%',
|
||||
transition: 'top 100ms, visibility 100ms',
|
||||
top: props.showMenu ? '0' : '100%',
|
||||
visibility: props.showMenu ? 'visible' : 'hidden',
|
||||
boxShadow:
|
||||
'rgb(48, 54, 61) 0px 0px 0px 1px, rgba(1, 4, 9, 0.4) 0px 6px 12px -3px, rgba(1, 4, 9, 0.4) 0px 6px 18px 0px',
|
||||
},
|
||||
zIndex: 2,
|
||||
}}
|
||||
@ -102,12 +103,11 @@ export function NavigationMenu(props: NavigationMenuProps): JSX.Element {
|
||||
lineHeight: '1',
|
||||
'@mdDown': {
|
||||
pb: '0px',
|
||||
pt: '5px',
|
||||
px: '15px',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<SpanBox css={{ mr: 'auto', '@mdDown': { display: 'none' } }}>
|
||||
<SpanBox css={{ mr: 'auto' }}>
|
||||
<Button
|
||||
style="plainIcon"
|
||||
onClick={(event) => {
|
||||
@ -121,25 +121,6 @@ export function NavigationMenu(props: NavigationMenuProps): JSX.Element {
|
||||
/>
|
||||
</Button>
|
||||
</SpanBox>
|
||||
|
||||
<Button
|
||||
style="plainIcon"
|
||||
css={{
|
||||
display: 'none',
|
||||
'@mdDown': {
|
||||
display: 'flex',
|
||||
ml: 'auto',
|
||||
pt: '10px',
|
||||
pb: '0px',
|
||||
},
|
||||
}}
|
||||
onClick={(event) => {
|
||||
props.setShowMenu(false)
|
||||
event.preventDefault()
|
||||
}}
|
||||
>
|
||||
<X size={30} />
|
||||
</Button>
|
||||
</Box>
|
||||
<LibraryNav {...props} />
|
||||
<Shortcuts {...props} />
|
||||
@ -178,7 +159,7 @@ const LibraryNav = (props: NavigationMenuProps): JSX.Element => {
|
||||
width: '100%',
|
||||
borderBottom: '1px solid $thBorderColor',
|
||||
px: '0px',
|
||||
pb: '25px',
|
||||
pb: '15px',
|
||||
}}
|
||||
alignment="start"
|
||||
distribution="start"
|
||||
@ -331,7 +312,7 @@ const Shortcuts = (props: NavigationMenuProps): JSX.Element => {
|
||||
fontFamily: '$display',
|
||||
fontSize: '14px',
|
||||
lineHeight: '125%',
|
||||
color: '$thLibraryMenuPrimary',
|
||||
color: '$homeTextSubtle',
|
||||
mb: '10px',
|
||||
px: '15px',
|
||||
}}
|
||||
|
||||
@ -22,6 +22,7 @@ export const SETTINGS_SECTION_1 = [
|
||||
]
|
||||
|
||||
export const SETTINGS_SECTION_2 = [
|
||||
{ name: 'Rules', destination: '/settings/rules' },
|
||||
{ name: 'Integrations', destination: '/settings/integrations' },
|
||||
{ name: 'Install', destination: '/settings/installation' },
|
||||
]
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
import { HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives'
|
||||
import { Button } from '../../elements/Button'
|
||||
import { PrimaryDropdown } from '../PrimaryDropdown'
|
||||
import { LogoBox } from '../../elements/LogoBox'
|
||||
import { ReactNode, useEffect, useState } from 'react'
|
||||
import { DEFAULT_HEADER_HEIGHT } from '../homeFeed/HeaderSpacer'
|
||||
import { theme } from '../../tokens/stitches.config'
|
||||
import { ReaderSettingsIcon } from '../../elements/icons/ReaderSettingsIcon'
|
||||
import { CircleUtilityMenuIcon } from '../../elements/icons/CircleUtilityMenuIcon'
|
||||
|
||||
function useScrollDirection() {
|
||||
const [scrollDirection, setScrollDirection] = useState('up')
|
||||
|
||||
@ -238,6 +238,8 @@ export const { styled, css, theme, getCssText, globalCss, keyframes, config } =
|
||||
homeActionHoverBg: '#DFDFDF',
|
||||
homeDivider: '#D9D9D9',
|
||||
|
||||
backgroundMedium: '#FFFFFF',
|
||||
|
||||
thLibraryAISummaryBorder: '#6A6968',
|
||||
thLibraryAISummaryBackground: '#343434',
|
||||
|
||||
@ -273,7 +275,7 @@ const darkThemeSpec = {
|
||||
colorScheme: 'dark',
|
||||
},
|
||||
shadows: {
|
||||
cardBoxShadow: '0px 4px 8px rgba(0, 0, 0, 0.50);',
|
||||
cardBoxShadow: '0px 4px 8px rgba(0, 0, 0, 0.35);',
|
||||
},
|
||||
colors: {
|
||||
grayBase: '#252525',
|
||||
@ -392,6 +394,8 @@ const darkThemeSpec = {
|
||||
homeActionHoverBg: '#515151',
|
||||
homeDivider: '#3D3D3D',
|
||||
|
||||
backgroundMedium: '#323232',
|
||||
|
||||
thLibraryAISummaryBorder: '#6A6968',
|
||||
thLibraryAISummaryBackground: '#343434',
|
||||
|
||||
@ -431,6 +435,8 @@ const apolloThemeSpec = {
|
||||
|
||||
thBackground: '#474747',
|
||||
thBackground2: '#515151',
|
||||
backgroundMedium: '#525252',
|
||||
|
||||
thLibraryMultiselectHover: '#EEE8D5',
|
||||
},
|
||||
}
|
||||
@ -456,6 +462,7 @@ const sepiaThemeSpec = {
|
||||
thBackground: '#FDF6E3',
|
||||
|
||||
homeCardHover: '#EEE8D5',
|
||||
backgroundMedium: '#EEE8D5',
|
||||
homeDivider: '#DDD6C1',
|
||||
homeActionHoverBg: '#DDD6C1',
|
||||
|
||||
|
||||
@ -8,9 +8,10 @@ export function usePersistedState<T>({
|
||||
key: string
|
||||
initialValue: T
|
||||
isSessionStorage?: boolean
|
||||
}): [T, (x: T | ((prev: T) => T)) => void] {
|
||||
}): [T, (x: T | ((prev: T) => T)) => void, boolean] {
|
||||
// State to store our value
|
||||
// Pass initial state function to useState so logic is only executed once
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [storedValue, setStoredValue] = useState(initialValue)
|
||||
|
||||
useEffect(() => {
|
||||
@ -27,6 +28,7 @@ export function usePersistedState<T>({
|
||||
if (item) {
|
||||
setStoredValue(JSON.parse(item))
|
||||
}
|
||||
setIsLoading(false)
|
||||
} catch (error) {
|
||||
// If error also return initialValue
|
||||
console.log(error)
|
||||
@ -56,5 +58,5 @@ export function usePersistedState<T>({
|
||||
}
|
||||
}
|
||||
|
||||
return [storedValue, setValue]
|
||||
return [storedValue, setValue, isLoading]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user