mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Pull in new highlight cards
This commit is contained in:
parent
bbb812f196
commit
5ea67a0bea
8 changed files with 193 additions and 3 deletions
|
|
@ -447,6 +447,8 @@ export const searchPages = async (
|
|||
body,
|
||||
})
|
||||
|
||||
console.log('resopnse', response)
|
||||
|
||||
if (response.body.hits.total.value === 0) {
|
||||
return [[], 0]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,3 +177,7 @@ export const StyledImg = styled('img', {
|
|||
export const StyledAnchor = styled('a', {
|
||||
textDecoration: 'none'
|
||||
})
|
||||
|
||||
export const StyledMark = styled('mark', {
|
||||
|
||||
})
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
import { styled } from '@stitches/react'
|
||||
import { VStack, HStack } from '../../elements/LayoutPrimitives'
|
||||
import { StyledMark, StyledText } from '../../elements/StyledText'
|
||||
import { LinkedItemCardAction, LinkedItemCardProps } from './CardTypes'
|
||||
|
||||
export interface HighlightItemCardProps
|
||||
extends Pick<LinkedItemCardProps, 'item'> {
|
||||
handleAction: (action: LinkedItemCardAction) => void
|
||||
}
|
||||
|
||||
export const PreviewImage = styled('img', {
|
||||
objectFit: 'cover',
|
||||
cursor: 'pointer',
|
||||
})
|
||||
|
||||
export function HighlightItemCard(props: HighlightItemCardProps): JSX.Element {
|
||||
return (
|
||||
<VStack
|
||||
css={{
|
||||
p: '$2',
|
||||
height: '100%',
|
||||
maxWidth: '498px',
|
||||
borderRadius: '6px',
|
||||
cursor: 'pointer',
|
||||
wordBreak: 'break-word',
|
||||
overflow: 'clip',
|
||||
border: '1px solid $grayBorder',
|
||||
boxShadow: '0px 3px 11px rgba(32, 31, 29, 0.04)',
|
||||
bg: '$grayBg',
|
||||
'&:focus': {
|
||||
bg: '$grayBgActive',
|
||||
},
|
||||
'&:hover': {
|
||||
bg: '$grayBgActive',
|
||||
},
|
||||
}}
|
||||
alignment="start"
|
||||
distribution="start"
|
||||
onClick={() => {
|
||||
props.handleAction('showDetail')
|
||||
}}
|
||||
>
|
||||
<StyledText
|
||||
css={{
|
||||
lineHeight: '20px',
|
||||
}}
|
||||
>
|
||||
<StyledMark
|
||||
css={{
|
||||
background: '$highlightBackground',
|
||||
color: '$highlightText',
|
||||
}}
|
||||
>
|
||||
{props.item.quote}
|
||||
</StyledMark>
|
||||
</StyledText>
|
||||
<HStack
|
||||
css={{
|
||||
marginTop: 'auto',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
{props.item.image && (
|
||||
<PreviewImage
|
||||
src={props.item.image}
|
||||
alt="Preview Image"
|
||||
width={16}
|
||||
height={16}
|
||||
css={{ borderRadius: '50%' }}
|
||||
onError={(e) => {
|
||||
;(e.target as HTMLElement).style.display = 'none'
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<StyledText
|
||||
css={{
|
||||
marginLeft: '$2',
|
||||
fontWeight: '700',
|
||||
}}
|
||||
>
|
||||
{props.item.title
|
||||
.substring(0, 50)
|
||||
.concat(props.item.title.length > 50 ? '...' : '')}
|
||||
</StyledText>
|
||||
</HStack>
|
||||
</VStack>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import { GridLinkedItemCard } from './GridLinkedItemCard'
|
||||
import { ListLinkedItemCard } from './ListLinkedItemCard'
|
||||
import type { LinkedItemCardProps } from './CardTypes'
|
||||
import { HighlightItemCard } from './HighlightItemCard'
|
||||
import { PageType } from '../../../lib/networking/fragments/articleFragment'
|
||||
|
||||
const siteName = (originalArticleUrl: string, itemUrl: string): string => {
|
||||
try {
|
||||
|
|
@ -15,6 +17,9 @@ const siteName = (originalArticleUrl: string, itemUrl: string): string => {
|
|||
export function LinkedItemCard(props: LinkedItemCardProps): JSX.Element {
|
||||
const originText = siteName(props.item.originalArticleUrl, props.item.url)
|
||||
|
||||
if (props.item.pageType === PageType.HIGHLIGHTS) {
|
||||
return <HighlightItemCard {...props} />
|
||||
}
|
||||
if (props.layout == 'LIST_LAYOUT') {
|
||||
return <ListLinkedItemCard {...props} originText={originText} />
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ const timeZoneHourDiff = -new Date().getTimezoneOffset() / 60
|
|||
const SAVED_SEARCHES: Record<string, string> = {
|
||||
Inbox: `in:inbox`,
|
||||
'Read Later': `in:inbox -label:Newsletter`,
|
||||
Highlighted: `in:inbox has:highlights`,
|
||||
Highlights: `type:highlights`,
|
||||
Today: `in:inbox saved:${
|
||||
new Date(new Date().getTime() - 24 * 3600000).toISOString().split('T')[0]
|
||||
}Z${timeZoneHourDiff.toLocaleString('en-US', {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,16 @@ export enum State {
|
|||
FAILED = 'FAILED',
|
||||
}
|
||||
|
||||
export enum PageType {
|
||||
ARTICLE = 'ARTICLE',
|
||||
BOOK = 'BOOK',
|
||||
FILE = 'FILE',
|
||||
PROFILE = 'PROFILE',
|
||||
WEBSITE = 'WEBSITE',
|
||||
HIGHLIGHTS = 'HIGHLIGHTS',
|
||||
UNKNOWN = 'UNKNOWN',
|
||||
}
|
||||
|
||||
export type ArticleFragmentData = {
|
||||
id: string
|
||||
title: string
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { gql } from 'graphql-request'
|
||||
import useSWRInfinite from 'swr/infinite'
|
||||
import { gqlFetcher } from '../networkHelpers'
|
||||
import type { ArticleFragmentData } from '../fragments/articleFragment'
|
||||
import type { ArticleFragmentData, PageType, State } from '../fragments/articleFragment'
|
||||
import { ContentReader } from '../fragments/articleFragment'
|
||||
import { setLinkArchivedMutation } from '../mutations/setLinkArchivedMutation'
|
||||
import { deleteLinkMutation } from '../mutations/deleteLinkMutation'
|
||||
|
|
@ -73,6 +73,8 @@ export type LibraryItemNode = {
|
|||
shortId: string
|
||||
quote: string
|
||||
annotation: string
|
||||
state: State
|
||||
pageType: PageType
|
||||
}
|
||||
|
||||
export type PageInfo = {
|
||||
|
|
@ -195,6 +197,8 @@ export function useGetLibraryItemsQuery({
|
|||
let responseError = error
|
||||
let responsePages = data as LibraryItemsData[] | undefined
|
||||
|
||||
console.log('data', data)
|
||||
|
||||
// We need to check the response errors here and return the error
|
||||
// it will be nested in the data pages, if there is one error,
|
||||
// we invalidate the data and return the error. We also zero out
|
||||
|
|
@ -330,7 +334,8 @@ export function useGetLibraryItemsQuery({
|
|||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
const res = {
|
||||
isValidating,
|
||||
itemsPages: responsePages || undefined,
|
||||
itemsDataError: responseError,
|
||||
|
|
@ -339,4 +344,8 @@ export function useGetLibraryItemsQuery({
|
|||
size,
|
||||
setSize,
|
||||
}
|
||||
|
||||
console.log('itemsPages', responsePages, 'error:', responseError)
|
||||
|
||||
return res
|
||||
}
|
||||
|
|
|
|||
71
packages/web/stories/HighlightItemCard.stories.tsx
Normal file
71
packages/web/stories/HighlightItemCard.stories.tsx
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import { ComponentStory, ComponentMeta } from '@storybook/react'
|
||||
import { HighlightItemCard, HighlightItemCardProps } from '../components/patterns/LibraryCards/HighlightItemCard'
|
||||
import { updateThemeLocally } from '../lib/themeUpdater'
|
||||
import { ThemeId } from '../components/tokens/stitches.config'
|
||||
import { PageType, State } from '../lib/networking/fragments/articleFragment'
|
||||
|
||||
export default {
|
||||
title: 'Components/HighlightItemCard',
|
||||
component: HighlightItemCard,
|
||||
argTypes: {
|
||||
item: {
|
||||
description: 'The highlight.',
|
||||
},
|
||||
handleAction: {
|
||||
description: 'Action that fires on click.'
|
||||
}
|
||||
}
|
||||
} as ComponentMeta<typeof HighlightItemCard>
|
||||
|
||||
const highlight: HighlightItemCardProps = {
|
||||
handleAction: () => console.log('Handling Action'),
|
||||
item:{
|
||||
id: "nnnnn",
|
||||
shortId: "shortId",
|
||||
quote: "children not only participate in herding work, but are also encouraged to act independently in most other areas of life. They have a say in deciding when to eat, when to sleep, and what to wear, even at temperatures of -30C (-22F).",
|
||||
annotation: "Okay… this is wild! I love this independence. Wondering how I can reponsibly instill this type of indepence in my own kids…",
|
||||
createdAt: '',
|
||||
description: '',
|
||||
isArchived: false,
|
||||
originalArticleUrl: 'https://example.com',
|
||||
ownedByViewer: true,
|
||||
pageId: '1',
|
||||
readingProgressAnchorIndex: 12,
|
||||
readingProgressPercent: 50,
|
||||
slug: 'slug',
|
||||
title: "This is a title",
|
||||
uploadFileId: '1',
|
||||
url: 'https://example.com',
|
||||
author: 'Author',
|
||||
image: 'https://logos-world.net/wp-content/uploads/2021/11/Unity-New-Logo.png',
|
||||
state: State.SUCCEEDED,
|
||||
pageType: PageType.HIGHLIGHTS,
|
||||
},
|
||||
}
|
||||
|
||||
const Template = (props: HighlightItemCardProps) => <HighlightItemCard {...props} />
|
||||
|
||||
export const LightHighlightItemCard: ComponentStory<
|
||||
typeof HighlightItemCard
|
||||
> = (args: any) => {
|
||||
updateThemeLocally(ThemeId.Light)
|
||||
return (
|
||||
<Template {...args}/>
|
||||
)
|
||||
}
|
||||
export const DarkHighlightItemCard: ComponentStory<
|
||||
typeof HighlightItemCard
|
||||
> = (args: any) => {
|
||||
updateThemeLocally(ThemeId.Dark)
|
||||
return (
|
||||
<Template {...args}/>
|
||||
)
|
||||
}
|
||||
|
||||
LightHighlightItemCard.args = {
|
||||
...highlight
|
||||
}
|
||||
|
||||
DarkHighlightItemCard.args = {
|
||||
...highlight
|
||||
}
|
||||
Loading…
Reference in a new issue