Add more information on the feeds page

This commit is contained in:
Jackson Harper 2024-02-07 13:02:19 +08:00
parent 95ad56f0f2
commit 70513b5244
10 changed files with 404 additions and 10 deletions

View file

@ -0,0 +1,67 @@
import { ReactNode, useEffect, useMemo, useRef } from 'react'
import { styled } from '../tokens/stitches.config'
import { Box, HStack, VStack } from './LayoutPrimitives'
import { Button } from './Button'
import { DropdownMenu } from '@radix-ui/react-dropdown-menu'
import { ArrowDown } from 'phosphor-react'
import { Dropdown, DropdownOption } from './DropdownElements'
import { CaretDownIcon } from './icons/CaretDownIcon'
type SplitButtonProps = {
title: string
}
const CaretButton = (): JSX.Element => {
return (
<VStack
css={{
width: '20px',
height: '100%',
alignItems: 'center',
bg: '#6A6968',
border: '0px solid transparent',
borderTopRightRadius: '5px',
borderBottomRightRadius: '5px',
borderTopLeftRadius: '0px',
borderBottomLeftRadius: '0px',
}}
>
<CaretDownIcon size={8} color="#EDEDED" />
</VStack>
)
}
export const SplitButton = (props: SplitButtonProps): JSX.Element => {
return (
<HStack css={{ height: '27px', gap: '1px' }}>
<Button
css={{
display: 'flex',
minWidth: '70px',
bg: '#6A6968',
fontSize: '12px',
fontFamily: '$inter',
border: '0px solid transparent',
borderTopLeftRadius: '5px',
borderBottomLeftRadius: '5px',
borderTopRightRadius: '0px',
borderBottomRightRadius: '0px',
'&:hover': {
opacity: 0.7,
border: '0px solid transparent',
},
'&:focus': {
outline: 'none',
border: '0px solid transparent',
},
}}
>
{props.title}
</Button>
{/* <Divider></Divider> */}
<Dropdown triggerElement={<CaretButton />}>
<DropdownOption onSelect={() => console.log()} title="Archive (e)" />
</Dropdown>
</HStack>
)
}

View file

@ -0,0 +1,44 @@
/* eslint-disable functional/no-class */
/* eslint-disable functional/no-this-expression */
import { IconProps } from './IconProps'
import React from 'react'
export class FollowingIcon extends React.Component<IconProps> {
render() {
const size = (this.props.size || 26).toString()
const color = (this.props.color || '#2A2A2A').toString()
return (
<svg
width={size}
height={size}
viewBox="0 0 25 25"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M12.5 4.5L4.5 8.5L12.5 12.5L20.5 8.5L12.5 4.5Z"
fill={color}
stroke={color}
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M4.5 12.5L12.5 16.5L20.5 12.5"
stroke={color}
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M4.5 16.5L12.5 20.5L20.5 16.5"
stroke={color}
stroke-linecap="round"
stroke-linejoin="round"
/>
</g>
</svg>
)
}
}

View file

@ -0,0 +1,40 @@
/* eslint-disable functional/no-class */
/* eslint-disable functional/no-this-expression */
import { IconProps } from './IconProps'
import React from 'react'
export class HeaderCheckboxIcon extends React.Component<IconProps> {
render() {
const size = (this.props.size || 26).toString()
const color = (this.props.color || '#2A2A2A').toString()
return (
<svg
width="40"
height="40"
viewBox="0 0 40 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
x="0.5"
y="0.5"
width="39"
height="39"
rx="19.5"
stroke="#3D3D3D"
/>
<g>
<path
d="M12.5 14.1667C12.5 13.7246 12.6756 13.3007 12.9882 12.9882C13.3007 12.6756 13.7246 12.5 14.1667 12.5H25.8333C26.2754 12.5 26.6993 12.6756 27.0118 12.9882C27.3244 13.3007 27.5 13.7246 27.5 14.1667V25.8333C27.5 26.2754 27.3244 26.6993 27.0118 27.0118C26.6993 27.3244 26.2754 27.5 25.8333 27.5H14.1667C13.7246 27.5 13.3007 27.3244 12.9882 27.0118C12.6756 26.6993 12.5 26.2754 12.5 25.8333V14.1667Z"
stroke="#D9D9D9"
strokeWidth="1.25"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
</svg>
)
}
}

View file

@ -0,0 +1,47 @@
/* eslint-disable functional/no-class */
/* eslint-disable functional/no-this-expression */
import { IconProps } from './IconProps'
import React from 'react'
export class HeaderSearchIcon extends React.Component<IconProps> {
render() {
const size = (this.props.size || 26).toString()
const color = (this.props.color || '#2A2A2A').toString()
return (
<svg
width="40"
height="40"
viewBox="0 0 40 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
x="0.5"
y="0.5"
width="39"
height="39"
rx="19.5"
stroke="#3D3D3D"
/>
<g>
<path
d="M12.5 18.3333C12.5 19.0994 12.6509 19.8579 12.944 20.5657C13.2372 21.2734 13.6669 21.9164 14.2085 22.4581C14.7502 22.9998 15.3933 23.4295 16.101 23.7226C16.8087 24.0158 17.5673 24.1667 18.3333 24.1667C19.0994 24.1667 19.8579 24.0158 20.5657 23.7226C21.2734 23.4295 21.9164 22.9998 22.4581 22.4581C22.9998 21.9164 23.4295 21.2734 23.7226 20.5657C24.0158 19.8579 24.1667 19.0994 24.1667 18.3333C24.1667 17.5673 24.0158 16.8087 23.7226 16.101C23.4295 15.3933 22.9998 14.7502 22.4581 14.2085C21.9164 13.6669 21.2734 13.2372 20.5657 12.944C19.8579 12.6509 19.0994 12.5 18.3333 12.5C17.5673 12.5 16.8087 12.6509 16.101 12.944C15.3933 13.2372 14.7502 13.6669 14.2085 14.2085C13.6669 14.7502 13.2372 15.3933 12.944 16.101C12.6509 16.8087 12.5 17.5673 12.5 18.3333Z"
stroke="#D9D9D9"
strokeWidth="1.25"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M27.5 27.5L22.5 22.5"
stroke="#D9D9D9"
strokeWidth="1.25"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
</svg>
)
}
}

View file

@ -0,0 +1,61 @@
/* eslint-disable functional/no-class */
/* eslint-disable functional/no-this-expression */
import { IconProps } from './IconProps'
import React from 'react'
export class HeaderToggleGridIcon extends React.Component<IconProps> {
render() {
const size = (this.props.size || 26).toString()
const color = (this.props.color || '#2A2A2A').toString()
return (
<svg
width="40"
height="40"
viewBox="0 0 40 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
x="0.5"
y="0.5"
width="39"
height="39"
rx="19.5"
stroke="#3D3D3D"
/>
<g>
<path
d="M13.3333 14.1654C13.3333 13.9444 13.4211 13.7324 13.5774 13.5761C13.7337 13.4198 13.9457 13.332 14.1667 13.332H17.5C17.721 13.332 17.933 13.4198 18.0893 13.5761C18.2455 13.7324 18.3333 13.9444 18.3333 14.1654V17.4987C18.3333 17.7197 18.2455 17.9317 18.0893 18.088C17.933 18.2442 17.721 18.332 17.5 18.332H14.1667C13.9457 18.332 13.7337 18.2442 13.5774 18.088C13.4211 17.9317 13.3333 17.7197 13.3333 17.4987V14.1654Z"
stroke="#D9D9D9"
strokeWidth="1.25"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M21.6667 14.1654C21.6667 13.9444 21.7545 13.7324 21.9107 13.5761C22.067 13.4198 22.279 13.332 22.5 13.332H25.8333C26.0543 13.332 26.2663 13.4198 26.4226 13.5761C26.5789 13.7324 26.6667 13.9444 26.6667 14.1654V17.4987C26.6667 17.7197 26.5789 17.9317 26.4226 18.088C26.2663 18.2442 26.0543 18.332 25.8333 18.332H22.5C22.279 18.332 22.067 18.2442 21.9107 18.088C21.7545 17.9317 21.6667 17.7197 21.6667 17.4987V14.1654Z"
stroke="#D9D9D9"
strokeWidth="1.25"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M13.3333 22.5013C13.3333 22.2803 13.4211 22.0683 13.5774 21.912C13.7337 21.7558 13.9457 21.668 14.1667 21.668H17.5C17.721 21.668 17.933 21.7558 18.0893 21.912C18.2455 22.0683 18.3333 22.2803 18.3333 22.5013V25.8346C18.3333 26.0556 18.2455 26.2676 18.0893 26.4239C17.933 26.5802 17.721 26.668 17.5 26.668H14.1667C13.9457 26.668 13.7337 26.5802 13.5774 26.4239C13.4211 26.2676 13.3333 26.0556 13.3333 25.8346V22.5013Z"
stroke="#D9D9D9"
strokeWidth="1.25"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M21.6667 22.5013C21.6667 22.2803 21.7545 22.0683 21.9107 21.912C22.067 21.7558 22.279 21.668 22.5 21.668H25.8333C26.0543 21.668 26.2663 21.7558 26.4226 21.912C26.5789 22.0683 26.6667 22.2803 26.6667 22.5013V25.8346C26.6667 26.0556 26.5789 26.2676 26.4226 26.4239C26.2663 26.5802 26.0543 26.668 25.8333 26.668H22.5C22.279 26.668 22.067 26.5802 21.9107 26.4239C21.7545 26.2676 21.6667 26.0556 21.6667 25.8346V22.5013Z"
stroke="#D9D9D9"
strokeWidth="1.25"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
</svg>
)
}
}

View file

@ -0,0 +1,47 @@
/* eslint-disable functional/no-class */
/* eslint-disable functional/no-this-expression */
import { IconProps } from './IconProps'
import React from 'react'
export class HeaderToggleListIcon extends React.Component<IconProps> {
render() {
const size = (this.props.size || 26).toString()
const color = (this.props.color || '#2A2A2A').toString()
return (
<svg
width="40"
height="40"
viewBox="0 0 40 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
x="0.5"
y="0.5"
width="39"
height="39"
rx="19.5"
stroke="#3D3D3D"
/>
<g>
<path
d="M13.3334 14.9987C13.3334 14.5567 13.509 14.1327 13.8215 13.8202C14.1341 13.5076 14.558 13.332 15 13.332H25C25.4421 13.332 25.866 13.5076 26.1786 13.8202C26.4911 14.1327 26.6667 14.5567 26.6667 14.9987V16.6654C26.6667 17.1074 26.4911 17.5313 26.1786 17.8439C25.866 18.1564 25.4421 18.332 25 18.332H15C14.558 18.332 14.1341 18.1564 13.8215 17.8439C13.509 17.5313 13.3334 17.1074 13.3334 16.6654V14.9987Z"
stroke="#D9D9D9"
strokeWidth="1.25"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M13.3334 23.3346C13.3334 22.8926 13.509 22.4687 13.8215 22.1561C14.1341 21.8436 14.558 21.668 15 21.668H25C25.4421 21.668 25.866 21.8436 26.1786 22.1561C26.4911 22.4687 26.6667 22.8926 26.6667 23.3346V25.0013C26.6667 25.4433 26.4911 25.8673 26.1786 26.1798C25.866 26.4924 25.4421 26.668 25 26.668H15C14.558 26.668 14.1341 26.4924 13.8215 26.1798C13.509 25.8673 13.3334 25.4433 13.3334 25.0013V23.3346Z"
stroke="#D9D9D9"
strokeWidth="1.25"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
</svg>
)
}
}

View file

@ -0,0 +1,44 @@
/* eslint-disable functional/no-class */
/* eslint-disable functional/no-this-expression */
import { IconProps } from './IconProps'
import React from 'react'
export class FollowingIcon extends React.Component<IconProps> {
render() {
const size = (this.props.size || 26).toString()
const color = (this.props.color || '#2A2A2A').toString()
return (
<svg
width={size}
height={size}
viewBox="0 0 25 25"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M12.5 4.5L4.5 8.5L12.5 12.5L20.5 8.5L12.5 4.5Z"
fill={color}
stroke={color}
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M4.5 12.5L12.5 16.5L20.5 12.5"
stroke={color}
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M4.5 16.5L12.5 20.5L20.5 16.5"
stroke={color}
stroke-linecap="round"
stroke-linejoin="round"
/>
</g>
</svg>
)
}
}

View file

@ -0,0 +1,33 @@
/* eslint-disable functional/no-class */
/* eslint-disable functional/no-this-expression */
import { IconProps } from './IconProps'
import React from 'react'
export class LibraryIcon extends React.Component<IconProps> {
render() {
const size = (this.props.size || 26).toString()
const color = (this.props.color || '#2A2A2A').toString()
return (
<svg
width={size}
height={size}
viewBox="0 0 25 25"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M13.5 6.5H7.5C6.70435 6.5 5.94129 6.81607 5.37868 7.37868C4.81607 7.94129 4.5 8.70435 4.5 9.5V21.5L4.506 21.614C4.52514 21.7802 4.58565 21.9389 4.68199 22.0756C4.77833 22.2123 4.90743 22.3227 5.05746 22.3966C5.20749 22.4705 5.37366 22.5056 5.54077 22.4987C5.70788 22.4918 5.87059 22.4431 6.014 22.357L10.5 19.666L14.986 22.357C15.1377 22.4479 15.3108 22.4969 15.4876 22.4991C15.6645 22.5013 15.8387 22.4566 15.9926 22.3695C16.1465 22.2823 16.2746 22.156 16.3637 22.0032C16.4528 21.8505 16.4999 21.6768 16.5 21.5V9.5C16.5 8.70435 16.1839 7.94129 15.6213 7.37868C15.0587 6.81607 14.2956 6.5 13.5 6.5Z"
fill={color}
/>
<path
d="M17.5 2.5C18.2652 2.49996 19.0015 2.79233 19.5582 3.31728C20.115 3.84224 20.4501 4.56011 20.495 5.324L20.5 5.5V17.5C20.5 17.6673 20.4581 17.8319 20.3781 17.9788C20.298 18.1256 20.1824 18.2501 20.0419 18.3407C19.9013 18.4314 19.7402 18.4853 19.5734 18.4976C19.4066 18.5098 19.2393 18.4801 19.087 18.411L18.986 18.357L17.986 17.757C17.8004 17.6456 17.656 17.4769 17.5744 17.2764C17.4929 17.0759 17.4786 16.8543 17.5337 16.645C17.5888 16.4357 17.7104 16.2499 17.8801 16.1156C18.0499 15.9812 18.2586 15.9056 18.475 15.9L18.5 15.901V5.5C18.5 5.25507 18.41 5.01866 18.2473 4.83563C18.0845 4.65259 17.8602 4.53566 17.617 4.507L17.5 4.5H11.499C11.3432 4.49965 11.1894 4.53572 11.05 4.60535C10.9106 4.67497 10.7893 4.77621 10.696 4.901L10.566 5.098C10.4124 5.29946 10.1881 5.43512 9.9383 5.47756C9.68854 5.52001 9.43199 5.46608 9.22046 5.32667C9.00893 5.18726 8.8582 4.97276 8.79871 4.7265C8.73923 4.48025 8.77542 4.2206 8.89999 4C9.14644 3.57292 9.49437 3.21316 9.91298 2.95258C10.3316 2.69199 10.808 2.53861 11.3 2.506L11.5 2.5H17.5Z"
fill={color}
/>
</g>
</svg>
)
}
}

View file

@ -22,8 +22,9 @@ export type Subscription = {
createdAt: string
updatedAt: string
lastFetchedAt?: string
autoAddToLibrary?: boolean
isPrivate?: boolean
mostRecentItemDate?: string
fetchContent?: boolean
}
type SubscriptionsQueryResponse = {
@ -63,8 +64,8 @@ export function useGetSubscriptionsQuery(
createdAt
updatedAt
lastFetchedAt
autoAddToLibrary
isPrivate
fetchContent
mostRecentItemDate
}
}
... on SubscriptionsError {

View file

@ -2,7 +2,11 @@ import { useRouter } from 'next/router'
import { FloppyDisk, Pencil, XCircle } from 'phosphor-react'
import { useMemo, useState } from 'react'
import { FormInput } from '../../../components/elements/FormElements'
import { HStack, SpanBox } from '../../../components/elements/LayoutPrimitives'
import {
HStack,
SpanBox,
VStack,
} from '../../../components/elements/LayoutPrimitives'
import { ConfirmationModal } from '../../../components/patterns/ConfirmationModal'
import {
EmptySettingsRow,
@ -200,19 +204,25 @@ export default function Rss(): JSX.Element {
}}
deleteTitle="Unsubscribe"
sublineElement={
<SpanBox
<VStack
css={{
my: '8px',
fontSize: '11px',
}}
>
{`URL: ${subscription.url}, `}
{`Last fetched: ${
<SpanBox>{`URL: ${subscription.url}`}</SpanBox>
<SpanBox>{`Last refreshed: ${
subscription.lastFetchedAt
? formattedDateTime(subscription.lastFetchedAt)
: 'Never'
}`}
</SpanBox>
}`}</SpanBox>
<SpanBox>
{subscription.mostRecentItemDate &&
`Most recent item: ${formattedDateTime(
subscription.mostRecentItemDate
)}`}
</SpanBox>
</VStack>
}
onClick={() => {
router.push(`/home?q=in:inbox rss:"${subscription.url}"`)