import { Account } from '@/db' import { TextInput } from 'flowbite-react' import { Entity, MegalodonInterface } from 'megalodon' import { useEffect, useState, useCallback } from 'react' import { Virtuoso } from 'react-virtuoso' import Status from './status/Status' import { FormattedMessage, useIntl } from 'react-intl' type Props = { timeline: string account: Account client: MegalodonInterface } export default function Timeline(props: Props) { const [statuses, setStatuses] = useState>([]) const { formatMessage } = useIntl() useEffect(() => { const f = async () => { const res = await loadTimeline(props.timeline, props.client) setStatuses(res) } f() }, [props.timeline, props.client]) const loadTimeline = async (tl: string, client: MegalodonInterface, maxId?: string): Promise> => { let options = { limit: 30 } if (maxId) { options = Object.assign({}, options, { max_id: maxId }) } switch (tl) { case 'home': { const res = await client.getHomeTimeline(options) return res.data } case 'local': { const res = await client.getLocalTimeline(options) return res.data } case 'public': { const res = await client.getPublicTimeline(options) return res.data } default: { return [] } } } const updateStatus = (current: Array, status: Entity.Status) => { const renew = current.map(s => { if (s.id === status.id) { return status } else if (s.reblog && s.reblog.id === status.id) { return Object.assign({}, s, { reblog: status }) } else if (status.reblog && s.id === status.reblog.id) { return status.reblog } else if (status.reblog && s.reblog && s.reblog.id === status.reblog.id) { return Object.assign({}, s, { reblog: status.reblog }) } else { return s } }) return renew } const loadMore = useCallback(async () => { console.debug('appending') const maxId = statuses[statuses.length - 1].id const append = await loadTimeline(props.timeline, props.client, maxId) setStatuses(last => [...last, ...append]) }, [props.client, statuses, setStatuses]) return (
( setStatuses(current => updateStatus(current, status))} /> )} />
) }