Move text utils into single place

This commit is contained in:
Jackson Harper
2024-08-26 12:58:24 +08:00
parent 632d5ad553
commit 31614f3f02
13 changed files with 20 additions and 422 deletions

View File

@ -1,23 +1,18 @@
import { NavigationLayout } from '../templates/NavigationLayout'
import { Box, HStack, VStack } from '../elements/LayoutPrimitives'
import { useFetchMore } from '../../lib/hooks/useFetchMoreScroll'
import { useCallback, useMemo, useState } from 'react'
import { useGetHighlights } from '../../lib/networking/queries/useGetHighlights'
import { Highlight } from '../../lib/networking/fragments/highlightFragment'
import { NextRouter, useRouter } from 'next/router'
import {
UserBasicData,
useGetViewerQuery,
} from '../../lib/networking/queries/useGetViewerQuery'
import { UserBasicData } from '../../lib/networking/queries/useGetViewerQuery'
import { SetHighlightLabelsModalPresenter } from '../templates/article/SetLabelsModalPresenter'
import { TrashIcon } from '../elements/icons/TrashIcon'
import { showErrorToast, showSuccessToast } from '../../lib/toastHelpers'
import { ConfirmationModal } from '../patterns/ConfirmationModal'
import { deleteHighlightMutation } from '../../lib/networking/mutations/deleteHighlightMutation'
import { LabelChip } from '../elements/LabelChip'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import { timeAgo } from '../patterns/LibraryCards/LibraryCardStyles'
import { timeAgo } from '../../lib/textFormatting'
import { HighlightHoverActions } from '../patterns/HighlightHoverActions'
import {
autoUpdate,

View File

@ -16,7 +16,7 @@ import { ArchiveActionIcon } from '../elements/icons/home/ArchiveActionIcon'
import { RemoveActionIcon } from '../elements/icons/home/RemoveActionIcon'
import { ShareActionIcon } from '../elements/icons/home/ShareActionIcon'
import Pagination from '../elements/Pagination'
import { timeAgo } from '../patterns/LibraryCards/LibraryCardStyles'
import { timeAgo } from '../../lib/textFormatting'
import { theme } from '../tokens/stitches.config'
import { useApplyLocalTheme } from '../../lib/hooks/useApplyLocalTheme'
import { useGetHiddenHomeSection } from '../../lib/networking/queries/useGetHiddenHomeSection'

View File

@ -1,6 +1,7 @@
import { Box, StyledLink } from './../elements/LayoutPrimitives'
import { StyledText } from './../../components/elements/StyledText'
import { formattedLongDate } from './../../lib/dateFormatting'
import { shouldHideUrl } from '../../lib/textFormatting'
type SubtitleStyle = 'footnote' | 'shareSubtitle'
@ -67,15 +68,6 @@ export function ReaderSavedInfo(props: ReaderSavedInfoProps): JSX.Element {
)
}
function shouldHideUrl(url: string): boolean {
const origin = new URL(url).origin
const hideHosts = ['https://storage.googleapis.com', 'https://omnivore.app']
if (hideHosts.indexOf(origin) != -1) {
return true
}
return false
}
function articleSubtitle(url: string, author?: string): string | undefined {
const origin = new URL(url).origin
const hideUrl = shouldHideUrl(url)

View File

@ -1,6 +1,3 @@
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import { useMemo } from 'react'
import { LibraryItemNode } from '../../../lib/networking/library_items/useLibraryItems'
import { HStack, SpanBox } from '../../elements/LayoutPrimitives'
import { RecommendedFlairIcon } from '../../elements/icons/RecommendedFlairIcon'
@ -9,8 +6,7 @@ import { FavoriteFlairIcon } from '../../elements/icons/FavoriteFlairIcon'
import { NewsletterFlairIcon } from '../../elements/icons/NewsletterFlairIcon'
import { FeedFlairIcon } from '../../elements/icons/FeedFlairIcon'
import { Label } from '../../../lib/networking/fragments/labelFragment'
dayjs.extend(relativeTime)
import { timeAgo } from '../../../lib/textFormatting'
export const MenuStyle = {
display: 'flex',
@ -69,26 +65,6 @@ export const AuthorInfoStyle = {
textOverflow: 'ellipsis',
}
export const timeAgo = (date: string | undefined): string => {
if (!date) {
return ''
}
return dayjs(date).fromNow()
}
const shouldHideUrl = (url: string): boolean => {
try {
const origin = new URL(url).origin
const hideHosts = ['https://storage.googleapis.com', 'https://omnivore.app']
if (hideHosts.indexOf(origin) != -1) {
return true
}
} catch {
console.log('invalid url item', url)
}
return false
}
export const FLAIR_ICON_NAMES = [
'favorite',
'pinned',
@ -148,27 +124,6 @@ export function FlairIcon(props: FlairIconProps): JSX.Element {
)
}
export const siteName = (
originalArticleUrl: string,
itemUrl: string,
siteName?: string
): string => {
if (siteName) {
return siteName
}
if (shouldHideUrl(originalArticleUrl)) {
return ''
}
try {
return new URL(originalArticleUrl).hostname.replace(/^www\./, '')
} catch {}
try {
return new URL(itemUrl).hostname.replace(/^www\./, '')
} catch {}
return ''
}
type LibraryItemMetadataProps = {
item: LibraryItemNode
showProgress?: boolean

View File

@ -10,11 +10,11 @@ import {
CardCheckbox,
LibraryItemMetadata,
MetaStyle,
siteName,
TitleStyle,
MenuStyle,
FLAIR_ICON_NAMES,
} from './LibraryCardStyles'
import { siteName } from '../../../lib/textFormatting'
import { sortedLabels } from '../../../lib/labelsSort'
import { LibraryHoverActions } from './LibraryHoverActions'
import {

View File

@ -1,7 +1,7 @@
import { Box, VStack, HStack, SpanBox } from '../../elements/LayoutPrimitives'
import { useCallback, useMemo, useState } from 'react'
import { CaretDown, CaretUp } from '@phosphor-icons/react'
import { MetaStyle, timeAgo, TitleStyle } from './LibraryCardStyles'
import { MetaStyle, TitleStyle } from './LibraryCardStyles'
import { styled } from '@stitches/react'
import { UserBasicData } from '../../../lib/networking/queries/useGetViewerQuery'
import { LibraryItemNode } from '../../../lib/networking/library_items/useLibraryItems'
@ -12,6 +12,7 @@ import { HighlightView } from '../HighlightView'
import { useRouter } from 'next/router'
import { showErrorToast } from '../../../lib/toastHelpers'
import { sortHighlights } from '../../../lib/highlights/sortHighlights'
import { timeAgo } from '../../../lib/textFormatting'
export const GridSeparator = styled(Box, {
height: '1px',

View File

@ -7,11 +7,11 @@ import {
CardCheckbox,
LibraryItemMetadata,
MetaStyle,
siteName,
TitleStyle,
MenuStyle,
FLAIR_ICON_NAMES,
} from './LibraryCardStyles'
import { siteName } from '../../../lib/textFormatting'
import { sortedLabels } from '../../../lib/labelsSort'
import { LIBRARY_LEFT_MENU_WIDTH } from '../../templates/navMenu/LibraryMenu'
import { LibraryHoverActions } from './LibraryHoverActions'

View File

@ -19,9 +19,9 @@ import { CoverImage } from '../../../elements/CoverImage'
import {
AuthorInfoStyle,
MetaStyle,
siteName,
TitleStyle,
} from '../../../patterns/LibraryCards/LibraryCardStyles'
import { siteName } from '../../../../lib/textFormatting'
import {
DiscoverItemCardProps,
DiscoverItemSubCardProps,

View File

@ -20,9 +20,9 @@ import { CoverImage } from '../../../elements/CoverImage'
import {
AuthorInfoStyle,
MetaStyle,
siteName,
TitleStyle,
} from '../../../patterns/LibraryCards/LibraryCardStyles'
import { siteName } from '../../../../lib/textFormatting'
import { CheckCircle, Circle } from '@phosphor-icons/react'
import {
DiscoverItemCardProps,

View File

@ -1,6 +1,6 @@
import { HStack } from '../../../elements/LayoutPrimitives'
import { timeAgo } from '../../../patterns/LibraryCards/LibraryCardStyles'
import { DiscoverFeedItem } from "../../../../lib/networking/queries/useGetDiscoverFeedItems"
import { DiscoverFeedItem } from '../../../../lib/networking/queries/useGetDiscoverFeedItems'
import { timeAgo } from '../../../../lib/textFormatting'
type DiscoverItemMetadataProps = {
item: DiscoverFeedItem

View File

@ -13,10 +13,8 @@ import { Dropdown, DropdownOption } from '../../elements/DropdownElements'
import { Box, HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives'
import { MenuTrigger } from '../../elements/MenuTrigger'
import {
MetaStyle,
timeAgo,
} from '../../patterns/LibraryCards/LibraryCardStyles'
import { MetaStyle } from '../../patterns/LibraryCards/LibraryCardStyles'
import { timeAgo } from '../../../lib/textFormatting'
import { LibraryHighlightGridCard } from '../../patterns/LibraryCards/LibraryHighlightGridCard'
import { NotebookContent } from '../article/Notebook'
import { EmptyHighlights } from './EmptyHighlights'
@ -36,9 +34,8 @@ type HighlightItemsLayoutProps = {
export function HighlightItemsLayout(
props: HighlightItemsLayoutProps
): JSX.Element {
const [currentItem, setCurrentItem] = useState<LibraryItem | undefined>(
undefined
)
const [currentItem, setCurrentItem] =
useState<LibraryItem | undefined>(undefined)
const listReducer = (
state: LibraryItem[],

View File

@ -1,317 +0,0 @@
import { LayoutType } from './HomeFeedContainer'
import { UserBasicData } from '../../../lib/networking/queries/useGetViewerQuery'
import { LibraryItem } from '../../../lib/networking/library_items/useLibraryItems'
import { HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives'
import { Toaster } from 'react-hot-toast'
import TopBarProgress from 'react-topbar-progress-indicator'
import { StyledText } from '../../elements/StyledText'
import { Button } from '../../elements/Button'
import { ArchiveIcon } from '../../elements/icons/ArchiveIcon'
import { TrashIcon } from '../../elements/icons/TrashIcon'
import { BrowserIcon } from '../../elements/icons/BrowserIcon'
import { styled } from '@stitches/react'
import { siteName } from '../../patterns/LibraryCards/LibraryCardStyles'
import { theme } from '../../tokens/stitches.config'
import { DotsThree } from '@phosphor-icons/react'
import { useState } from 'react'
type TLDRLayoutProps = {
layout: LayoutType
viewer?: UserBasicData
items: LibraryItem[]
isValidating: boolean
hasMore: boolean
totalItems: number
loadMore: () => void
}
const SiteIcon = styled('img', {
width: '22px',
height: '22px',
borderRadius: '100px',
})
export function TLDRLayout(props: TLDRLayoutProps): JSX.Element {
return (
<>
<VStack
alignment="start"
distribution="start"
css={{
mt: '30px',
gap: '50px',
height: '100%',
minHeight: '100vh',
px: '0px',
width: '100%',
maxWidth: '800px',
'@mdDown': {
p: '10px',
},
}}
>
<Toaster />
{props.isValidating && props.items.length == 0 && <TopBarProgress />}
{props.items.map((item) => {
const sourceName = siteName(
item.node.originalArticleUrl,
item.node.url,
item.node.siteName
)
const source =
sourceName == item.node.author ? undefined : item.node.author
return (
<VStack key={`tldr-${item.node.id}`} css={{ gap: '10px' }}>
<HStack
alignment="center"
distribution="start"
css={{
gap: '5px',
width: '100%',
height: '25px',
pb: 'red',
}}
>
<VStack
distribution="center"
alignment="center"
css={{
mr: '5px',
display: 'flex',
w: '22px',
h: '22px',
borderRadius: '100px',
bg: '$ctaBlue',
color: '$thTextSubtle',
}}
>
<SiteIcon src={item.node.siteIcon} />
</VStack>
{source && (
<SpanBox
css={{
display: 'flex',
fontFamily: '$inter',
fontSize: '16px',
maxWidth: '150px',
maxLines: '1',
textOverflow: 'ellipsis',
'@mdDown': {
fontSize: '12px',
},
}}
>
{item.node.siteName}
</SpanBox>
)}
{source && item.node.author && (
<SpanBox
css={{
maxLines: '1',
display: 'flex',
fontFamily: '$inter',
maxWidth: '150px',
textOverflow: 'ellipsis',
'@mdDown': {
fontSize: '12px',
},
}}
>
</SpanBox>
)}
{item.node.author && (
<SpanBox
css={{
display: 'flex',
fontFamily: '$inter',
fontSize: '16px',
maxWidth: '120px',
maxLines: '1',
textOverflow: 'ellipsis',
'@mdDown': {
fontSize: '12px',
},
}}
>
{item.node.author}
</SpanBox>
)}
<SpanBox css={{ ml: 'auto' }}>
<DotsThree
size={20}
color={theme.colors.thTextSubtle.toString()}
/>
</SpanBox>
</HStack>
<HStack
css={{
gap: '10px',
}}
>
<VStack
alignment="start"
distribution="start"
css={{ gap: '10px' }}
>
<SpanBox
css={{
fontFamily: '$inter',
fontWeight: '700',
fontSize: '20px',
wordBreak: 'break-all',
textDecoration: 'underline',
a: {
color: '$thTLDRText',
},
}}
>
<a href={``}>{item.node.title}</a>
</SpanBox>
<SpanBox
css={{
fontFamily: '$inter',
fontWeight: '500',
fontSize: '14px',
lineHeight: '30px',
color: '$thTLDRText',
}}
>
{item.node.aiSummary}
</SpanBox>
<HStack css={{ gap: '15px', pt: '5px' }}>
<ArchiveButton />
<RemoveButton />
<OpenOriginalButton />
</HStack>
</VStack>
</HStack>
</VStack>
)
})}
<HStack
distribution="center"
css={{ width: '100%', mt: '$2', mb: '$4' }}
>
{props.hasMore ? (
<Button
style="ctaGray"
css={{
cursor: props.isValidating ? 'not-allowed' : 'pointer',
}}
onClick={props.loadMore}
disabled={props.isValidating}
>
{props.isValidating ? 'Loading' : 'Load More'}
</Button>
) : (
<StyledText style="caption"></StyledText>
)}
</HStack>
</VStack>
</>
)
}
const ArchiveButton = (): JSX.Element => {
const [foreground, setForegroundColor] = useState<string>(
theme.colors.thTextContrast2.toString()
)
return (
<Button
title="Archive"
style="tldr"
css={{
'&:hover': {
bg: '$ctaBlue',
opacity: 1.0,
},
}}
onMouseEnter={(event) => {
setForegroundColor('white')
event.preventDefault()
}}
onMouseLeave={(event) => {
setForegroundColor(theme.colors.thTextContrast2.toString())
event.preventDefault()
}}
onClick={(e) => {
// props.setShowConfirmDelete(true)
e.preventDefault()
}}
>
<ArchiveIcon size={20} color={foreground} />
</Button>
)
}
const RemoveButton = (): JSX.Element => {
const [foreground, setForegroundColor] = useState<string>(
theme.colors.thTextContrast2.toString()
)
return (
<Button
title="Remove"
style="tldr"
css={{
'&:hover': {
bg: '$ctaBlue',
opacity: 1.0,
},
}}
onMouseEnter={(event) => {
setForegroundColor('white')
event.preventDefault()
}}
onMouseLeave={(event) => {
setForegroundColor(theme.colors.thTextContrast2.toString())
event.preventDefault()
}}
onClick={(e) => {
// props.setShowConfirmDelete(true)
e.preventDefault()
}}
>
<TrashIcon size={20} color={foreground} />
</Button>
)
}
const OpenOriginalButton = (): JSX.Element => {
const [foreground, setForegroundColor] = useState<string>(
theme.colors.thTextContrast2.toString()
)
return (
<Button
title="Open original"
style="tldr"
css={{
'&:hover': {
bg: '$ctaBlue',
opacity: 1.0,
},
}}
onMouseEnter={(event) => {
setForegroundColor('white')
event.preventDefault()
}}
onMouseLeave={(event) => {
setForegroundColor(theme.colors.thTextContrast2.toString())
event.preventDefault()
}}
onClick={(e) => {
// props.setShowConfirmDelete(true)
e.preventDefault()
}}
>
<BrowserIcon size={20} color={foreground} />
</Button>
)
}

View File

@ -1,33 +1,8 @@
import { styled } from '@stitches/react'
import { AddToLibraryActionIcon } from '../../components/elements/icons/home/AddToLibraryActionIcon'
import { ArchiveActionIcon } from '../../components/elements/icons/home/ArchiveActionIcon'
import { CommentActionIcon } from '../../components/elements/icons/home/CommentActionIcon'
import { RemoveActionIcon } from '../../components/elements/icons/home/RemoveActionIcon'
import { ShareActionIcon } from '../../components/elements/icons/home/ShareActionIcon'
import { useApplyLocalTheme } from '../../lib/hooks/useApplyLocalTheme'
import {
HStack,
SpanBox,
VStack,
} from './../../components/elements/LayoutPrimitives'
import * as HoverCard from '@radix-ui/react-hover-card'
import { SpanBox, VStack } from './../../components/elements/LayoutPrimitives'
import { Button } from '../../components/elements/Button'
import {
HomeItem,
HomeItemSource,
HomeItemSourceType,
HomeSection,
useGetHomeItems,
} from '../../lib/networking/queries/useGetHome'
import { timeAgo } from '../../components/patterns/LibraryCards/LibraryCardStyles'
import { theme } from '../../components/tokens/stitches.config'
import { useRouter } from 'next/router'
import {
SubscriptionType,
useGetSubscriptionsQuery,
} from '../../lib/networking/queries/useGetSubscriptionsQuery'
import { useCallback, useMemo } from 'react'
import { useGetHomeItems } from '../../lib/networking/queries/useGetHome'
import { useCallback } from 'react'
import { refreshHomeMutation } from '../../lib/networking/mutations/refreshHome'
export default function DebugHome(): JSX.Element {