Update setlabels to save on close, always use the modal

This commit is contained in:
Jackson Harper 2022-12-29 17:37:52 +08:00
parent 2c6b6ef3cc
commit e03da2475d
7 changed files with 102 additions and 92 deletions

View file

@ -20,6 +20,7 @@ import { useReaderSettings } from '../../../lib/hooks/useReaderSettings'
import { useRef } from 'react'
import { setLabelsMutation } from '../../../lib/networking/mutations/setLabelsMutation'
import { Label } from '../../../lib/networking/fragments/labelFragment'
import { SetLabelsModal } from './SetLabelsModal'
export type ArticleActionsMenuLayout = 'top' | 'side'
@ -102,12 +103,7 @@ export function ArticleActionsMenu(
tooltipContent="Adjust Display Settings"
tooltipSide={props.layout == 'side' ? 'right' : 'bottom'}
>
<SpanBox ref={displaySettingsButtonRef}>
<TextAa
size={24}
color={theme.colors.readerFont.toString()}
/>
</SpanBox>
<TextAa size={24} color={theme.colors.readerFont.toString()} />
</TooltipWrapped>
</Button>
<MenuSeparator layout={props.layout} />
@ -122,37 +118,56 @@ export function ArticleActionsMenu(
}}
>
{props.article ? (
<ActionDropdown
layout={props.layout}
triggerElement={
<>
<Button
style="articleActionIcon"
onClick={() => readerSettings.setShowSetLabelsModal(true)}
>
<TooltipWrapped
tooltipContent="Edit labels"
tooltipSide={props.layout == 'side' ? 'right' : 'bottom'}
>
<TagSimple
size={24}
color={theme.colors.readerFont.toString()}
/>
<SpanBox ref={displaySettingsButtonRef}>
<TagSimple
size={24}
color={theme.colors.readerFont.toString()}
/>
</SpanBox>
</TooltipWrapped>
}
>
<SetLabelsControl
provider={props.article}
save={(labels: Label[]) => {
if (props.article?.id) {
return setLabelsMutation(
props.article?.id,
labels.map((label) => label.id)
)
}
return Promise.resolve(undefined)
}}
onLabelsChanged={(labels) => {
props.articleActionHandler('refreshLabels', labels)
}}
/>
</ActionDropdown>
</Button>
<MenuSeparator layout={props.layout} />
</>
) : (
// <ActionDropdown
// layout={props.layout}
// triggerElement={
// <TooltipWrapped
// tooltipContent="Edit labels"
// tooltipSide={props.layout == 'side' ? 'right' : 'bottom'}
// >
// <TagSimple
// size={24}
// color={theme.colors.readerFont.toString()}
// />
// </TooltipWrapped>
// }
// >
// <SetLabelsControl
// provider={props.article}
// save={(labels: Label[]) => {
// if (props.article?.id) {
// return setLabelsMutation(
// props.article?.id,
// labels.map((label) => label.id)
// )
// }
// return Promise.resolve(undefined)
// }}
// onLabelsChanged={(labels) => {
// props.articleActionHandler('refreshLabels', labels)
// }}
// />
// </ActionDropdown>
<Button
style="articleActionIcon"
css={{
@ -254,6 +269,27 @@ export function ArticleActionsMenu(
}
/>
)}
{props.article && readerSettings.showSetLabelsModal && (
<SetLabelsModal
provider={props.article}
onOpenChange={(open: boolean) => {}}
onLabelsUpdated={(labels: Label[]) => {
props.articleActionHandler('refreshLabels', labels)
}}
save={(labels: Label[]) => {
if (props.article?.id) {
return (
setLabelsMutation(
props.article?.id,
labels.map((l) => l.id)
) ?? []
)
}
return Promise.resolve(labels)
}}
/>
)}
</>
)
}

View file

@ -584,8 +584,6 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
onOpenChange={function (open: boolean): void {
setLabelsTarget(undefined)
}}
// eslint-disable-next-line @typescript-eslint/no-empty-function
onLabelsChanged={function (labels: Label[]): void {}}
save={function (labels: Label[]): Promise<Label[] | undefined> {
const result = setLabelsForHighlight(
labelsTarget.id,

View file

@ -105,7 +105,7 @@ export function HighlightsModal(props: HighlightsModalProps): JSX.Element {
onOpenChange={function (open: boolean): void {
setLabelsTarget(undefined)
}}
onLabelsChanged={function (labels: Label[]): void {
onLabelsUpdated={function (labels: Label[]): void {
updateState({})
}}
save={function (labels: Label[]): Promise<Label[] | undefined> {

View file

@ -20,8 +20,11 @@ export interface LabelsProvider {
type SetLabelsControlProps = {
provider: LabelsProvider
onLabelsChanged: (labels: Label[]) => void
save: (labels: Label[]) => Promise<Label[] | undefined>
selectedLabels: Label[]
setSelectedLabels: (labels: Label[]) => void
onLabelsUpdated?: (labels: Label[]) => void
}
type HeaderProps = {
@ -239,9 +242,6 @@ export function SetLabelsControl(props: SetLabelsControlProps): JSX.Element {
const router = useRouter()
const [filterText, setFilterText] = useState('')
const { labels, revalidate } = useGetLabelsQuery()
const [selectedLabels, setSelectedLabels] = useState<Label[]>(
props.provider.labels ?? []
)
useEffect(() => {
setFocusedIndex(undefined)
@ -249,41 +249,33 @@ export function SetLabelsControl(props: SetLabelsControlProps): JSX.Element {
const isSelected = useCallback(
(label: Label): boolean => {
return selectedLabels.some((other) => {
return props.selectedLabels.some((other) => {
return other.id === label.id
})
},
[selectedLabels]
[props.selectedLabels]
)
const toggleLabel = useCallback(
async (label: Label) => {
console.log('toggling label: ', label)
let newSelectedLabels = [...selectedLabels]
let newSelectedLabels = [...props.selectedLabels]
if (isSelected(label)) {
newSelectedLabels = selectedLabels.filter((other) => {
newSelectedLabels = props.selectedLabels.filter((other) => {
return other.id !== label.id
})
} else {
newSelectedLabels = [...selectedLabels, label]
newSelectedLabels = [...props.selectedLabels, label]
}
setSelectedLabels(newSelectedLabels)
props.setSelectedLabels(newSelectedLabels)
props.provider.labels = newSelectedLabels
if (props.onLabelsChanged) {
props.onLabelsChanged(newSelectedLabels)
}
try {
const result = await props.save(newSelectedLabels)
console.log(' -- result of setting labels: ', result)
} catch (err) {
console.log(' -- error setting labels: ', err)
if (props.onLabelsUpdated) {
props.onLabelsUpdated(newSelectedLabels)
}
revalidate()
},
[isSelected, selectedLabels, setSelectedLabels]
[isSelected, props]
)
const filteredLabels = useMemo(() => {
@ -354,14 +346,7 @@ export function SetLabelsControl(props: SetLabelsControlProps): JSX.Element {
}
}
},
[
filterText,
filteredLabels,
focusedIndex,
isSelected,
selectedLabels,
setSelectedLabels,
]
[filterText, filteredLabels, focusedIndex, isSelected, props]
)
const createLabelFromFilterText = useCallback(async () => {
@ -378,7 +363,7 @@ export function SetLabelsControl(props: SetLabelsControlProps): JSX.Element {
} else {
showErrorToast('Failed to create label', { position: 'bottom-right' })
}
}, [filterText, selectedLabels, setSelectedLabels, toggleLabel])
}, [filterText, props, toggleLabel])
return (
<VStack

View file

@ -12,40 +12,30 @@ import { LabelsProvider, SetLabelsControl } from './SetLabelsControl'
type SetLabelsModalProps = {
provider: LabelsProvider
onLabelsUpdated?: (labels: Label[]) => void
onOpenChange: (open: boolean) => void
onLabelsChanged: (labels: Label[]) => void
save: (labels: Label[]) => Promise<Label[] | undefined>
}
export function SetLabelsModal(props: SetLabelsModalProps): JSX.Element {
const [selectedLabels, setSelectedLabels] = useState(props.provider.labels)
const [selectedLabels, setSelectedLabels] = useState(
props.provider.labels ?? []
)
const onOpenChange = useCallback(
async (open: boolean) => {
console.log('SetLabelsModal::onOpenChange: ', open, selectedLabels)
if (selectedLabels) {
const result = await props.save(selectedLabels)
console.log('SetLabelsModal::onOpenChange: ', result)
const result = await props.save(selectedLabels)
if (props.onLabelsUpdated) {
props.onLabelsUpdated(selectedLabels)
}
if (result) {
props.onLabelsChanged(result)
} else {
showErrorToast('Error updating labels')
}
} else {
console.log('SetLabelsModal::onOpenChange: no selectedLabels')
if (!result) {
showErrorToast('Error updating labels')
}
props.onOpenChange(open)
},
[props.onOpenChange]
)
const handleSave = useCallback(
(labels: Label[]) => {
console.log('setting selected labels: ', labels)
setSelectedLabels(labels)
return Promise.resolve(labels)
},
[selectedLabels, setSelectedLabels]
[props, selectedLabels, setSelectedLabels]
)
return (
@ -64,8 +54,9 @@ export function SetLabelsModal(props: SetLabelsModalProps): JSX.Element {
</SpanBox>
<SetLabelsControl
provider={props.provider}
save={handleSave}
onLabelsChanged={props.onLabelsChanged}
selectedLabels={selectedLabels}
setSelectedLabels={setSelectedLabels}
onLabelsUpdated={props.onLabelsUpdated}
/>
</VStack>
</ModalContent>

View file

@ -1205,7 +1205,7 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
{props.labelsTarget?.node.id && (
<SetLabelsModal
provider={props.labelsTarget.node}
onLabelsChanged={(labels: Label[]) => {
onLabelsUpdated={(labels: Label[]) => {
if (props.labelsTarget) {
props.labelsTarget.node.labels = labels
updateState({})

View file

@ -368,7 +368,7 @@ export default function Home(): JSX.Element {
{article && readerSettings.showSetLabelsModal && (
<SetLabelsModal
provider={article}
onLabelsChanged={(labels: Label[]) => {
onLabelsUpdated={(labels: Label[]) => {
actionHandler('refreshLabels', labels)
}}
save={(labels: Label[]) => {