Merge pull request #2510 from omnivore-app/feature/edit-rss

feature/edit rss
This commit is contained in:
Hongbo Wu
2023-07-19 22:18:36 +08:00
committed by GitHub
3 changed files with 168 additions and 12 deletions

View File

@ -1,4 +1,4 @@
import { Trash } from 'phosphor-react'
import { Pencil, Trash } from 'phosphor-react'
import { Toaster } from 'react-hot-toast'
import { Button } from '../../elements/Button'
import { Dropdown, DropdownOption } from '../../elements/DropdownElements'
@ -26,7 +26,7 @@ type CreateButtonProps = {
}
type SettingsTableRowProps = {
title: string
title: string | JSX.Element
isLast: boolean
onClick?: () => void
@ -39,12 +39,17 @@ type SettingsTableRowProps = {
onDelete?: () => void
dropdownItems?: JSX.Element
editTitle?: string
onEdit?: () => void
}
type MoreOptionsProps = {
title?: string
deleteTitle?: string
onDelete?: () => void
dropdownItems?: JSX.Element
editTitle?: string
onEdit?: () => void
}
const MoreOptions = (props: MoreOptionsProps) => (
@ -66,7 +71,33 @@ const MoreOptions = (props: MoreOptionsProps) => (
</Box>
}
>
{props.onDelete && props.title && (
{props.onEdit && props.editTitle && (
<DropdownOption
onSelect={() => {
props.onEdit && props.onEdit()
}}
>
<HStack alignment={'center'} distribution={'start'}>
<Pencil size={24} color={theme.colors.omnivoreLightGray.toString()} />
<SpanBox
css={{
color: theme.colors.omnivoreLightGray.toString(),
marginLeft: '8px',
border: 'none',
backgroundColor: 'transparent',
'&:hover': {
border: 'none',
backgroundColor: 'transparent',
},
}}
>
{props.editTitle}
</SpanBox>
</HStack>
</DropdownOption>
)}
{props.onDelete && props.deleteTitle && (
<DropdownOption
onSelect={() => {
props.onDelete && props.onDelete()
@ -86,7 +117,7 @@ const MoreOptions = (props: MoreOptionsProps) => (
},
}}
>
{props.title}
{props.deleteTitle}
</SpanBox>
</HStack>
</DropdownOption>
@ -192,9 +223,11 @@ export const SettingsTableRow = (props: SettingsTableRowProps): JSX.Element => {
}}
>
<MoreOptions
title={props.deleteTitle}
deleteTitle={props.deleteTitle}
onDelete={props.onDelete}
dropdownItems={props.dropdownItems}
editTitle={props.editTitle}
onEdit={props.onEdit}
/>
</Box>
</HStack>
@ -211,9 +244,11 @@ export const SettingsTableRow = (props: SettingsTableRowProps): JSX.Element => {
}}
>
<MoreOptions
title={props.deleteTitle}
deleteTitle={props.deleteTitle}
onDelete={props.onDelete}
dropdownItems={props.dropdownItems}
editTitle={props.editTitle}
onEdit={props.onEdit}
/>
</Box>
</HStack>

View File

@ -0,0 +1,51 @@
import { gql } from 'graphql-request'
import { gqlFetcher } from '../networkHelpers'
import { Subscription } from '../queries/useGetSubscriptionsQuery'
interface UpdateSubscriptionResult {
updateSubscription: UpdateSubscription
}
interface UpdateSubscription {
subscription: Subscription
errorCodes?: unknown[]
}
interface UpdateSubscriptionInput {
id: string
lastFetchedAt?: Date
name?: string
description?: string
}
export async function updateSubscriptionMutation(
input: UpdateSubscriptionInput
): Promise<any | undefined> {
const mutation = gql`
mutation UpdateSubscription($input: UpdateSubscriptionInput!) {
updateSubscription(input: $input) {
... on UpdateSubscriptionSuccess {
subscription {
id
lastFetchedAt
}
}
... on UpdateSubscriptionError {
errorCodes
}
}
}
`
try {
const data = (await gqlFetcher(mutation, {
input,
})) as UpdateSubscriptionResult
return data.updateSubscription.errorCodes
? undefined
: data.updateSubscription.subscription.id
} catch (error) {
console.log('updateSubscriptionMutation error', error)
return undefined
}
}

View File

@ -1,5 +1,8 @@
import { useRouter } from 'next/router'
import { FloppyDisk, Pencil, XCircle } from 'phosphor-react'
import { useState } from 'react'
import { FormInput } from '../../../components/elements/FormElements'
import { HStack } from '../../../components/elements/LayoutPrimitives'
import { StyledText } from '../../../components/elements/StyledText'
import { ConfirmationModal } from '../../../components/patterns/ConfirmationModal'
import {
@ -7,8 +10,10 @@ import {
SettingsTable,
SettingsTableRow,
} from '../../../components/templates/settings/SettingsTable'
import { theme } from '../../../components/tokens/stitches.config'
import { formattedShortTime } from '../../../lib/dateFormatting'
import { unsubscribeMutation } from '../../../lib/networking/mutations/unsubscribeMutation'
import { updateSubscriptionMutation } from '../../../lib/networking/mutations/updateSubscriptionMutation'
import {
SubscriptionType,
useGetSubscriptionsQuery,
@ -22,6 +27,22 @@ export default function Rss(): JSX.Element {
SubscriptionType.RSS
)
const [onDeleteId, setOnDeleteId] = useState<string>('')
const [onEditId, setOnEditId] = useState('')
const [name, setName] = useState('')
async function updateSubscription(): Promise<void> {
const result = await updateSubscriptionMutation({
id: onEditId,
name,
})
if (result) {
showSuccessToast('RSS feed updated', { position: 'bottom-right' })
} else {
showErrorToast('Failed to update', { position: 'bottom-right' })
}
revalidate()
}
async function onDelete(id: string): Promise<void> {
const result = await unsubscribeMutation('', id)
@ -54,7 +75,56 @@ export default function Rss(): JSX.Element {
return (
<SettingsTableRow
key={subscription.id}
title={subscription.name}
title={
<HStack
alignment={'center'}
distribution={'start'}
css={{ width: '400px' }}
>
<FormInput
value={onEditId ? name : subscription.name}
onClick={(e) => e.stopPropagation()}
onChange={(e) => setName(e.target.value)}
placeholder="Description"
disabled={!onEditId}
/>
{onEditId ? (
<HStack alignment={'center'} distribution={'start'}>
<FloppyDisk
style={{ cursor: 'pointer', marginLeft: '5px' }}
color={theme.colors.omnivoreCtaYellow.toString()}
onClick={async (e) => {
e.stopPropagation()
await updateSubscription()
setOnEditId('')
}}
>
Save
</FloppyDisk>
<XCircle
style={{ cursor: 'pointer', marginLeft: '5px' }}
color={theme.colors.omnivoreRed.toString()}
onClick={(e) => {
e.stopPropagation()
setOnEditId('')
}}
>
Cancel
</XCircle>
</HStack>
) : (
<Pencil
style={{ cursor: 'pointer', marginLeft: '5px' }}
color={theme.colors.omnivoreLightGray.toString()}
onClick={(e) => {
e.stopPropagation()
setName(subscription.name)
setOnEditId(subscription.id)
}}
/>
)}
</HStack>
}
isLast={i === subscriptions.length - 1}
onDelete={() => {
console.log('onDelete triggered: ', subscription.id)
@ -64,11 +134,8 @@ export default function Rss(): JSX.Element {
sublineElement={
<StyledText
css={{
my: '5px',
my: '8px',
fontSize: '11px',
a: {
color: '$omnivoreCtaYellow',
},
}}
>
{`URL: ${subscription.url}, `}
@ -79,6 +146,9 @@ export default function Rss(): JSX.Element {
}`}
</StyledText>
}
onClick={() => {
router.push(`/home?q=rss:"${subscription.url}"`)
}}
/>
)
})