import { Menu, MenuDivider, MenuItem } from '@szhsin/react-menu'; import { useRef } from 'preact/hooks'; import { useNavigate, useParams } from 'react-router-dom'; import { useSnapshot } from 'valtio'; import Icon from '../components/icon'; import Menu2 from '../components/menu2'; import Timeline from '../components/timeline'; import { api } from '../utils/api'; import { filteredItems } from '../utils/filters'; import states from '../utils/states'; import { saveStatus } from '../utils/states'; import useTitle from '../utils/useTitle'; const LIMIT = 20; function Public({ local, columnMode, ...props }) { const snapStates = useSnapshot(states); const isLocal = !!local; const params = columnMode ? {} : useParams(); const { masto, instance } = api({ instance: props?.instance || params.instance, }); const { masto: currentMasto, instance: currentInstance } = api(); const title = `${isLocal ? 'Local' : 'Federated'} timeline (${instance})`; useTitle(title, isLocal ? `/:instance?/p/l` : `/:instance?/p`); // const navigate = useNavigate(); const latestItem = useRef(); const publicIterator = useRef(); async function fetchPublic(firstLoad) { if (firstLoad || !publicIterator.current) { publicIterator.current = masto.v1.timelines.public.list({ limit: LIMIT, local: isLocal, remote: !isLocal, // Pixelfed }); } const results = await publicIterator.current.next(); let { value } = results; if (value?.length) { if (firstLoad) { latestItem.current = value[0].id; } // value = filteredItems(value, 'public'); value.forEach((item) => { saveStatus(item, instance); }); } return { ...results, value, }; } async function checkForUpdates() { try { const results = await masto.v1.timelines.public .list({ limit: 1, local: isLocal, since_id: latestItem.current, }) .next(); let { value } = results; const valueContainsLatestItem = value[0]?.id === latestItem.current; // since_id might not be supported if (value?.length && !valueContainsLatestItem) { value = filteredItems(value, 'public'); return true; } return false; } catch (e) { return false; } } return ( {isLocal ? 'Local timeline' : 'Federated timeline'}
{instance}
} id="public" instance={instance} emptyText="No one has posted anything yet." errorText="Unable to load posts" fetchItems={fetchPublic} checkForUpdates={checkForUpdates} useItemID headerStart={<>} boostsCarousel={snapStates.settings.boostsCarousel} // allowFilters filterContext="public" headerEnd={ } > {isLocal ? ( <> Switch to Federated ) : ( <> Switch to Local )} { let newInstance = prompt( 'Enter a new instance e.g. "mastodon.social"', ); if (!/\./.test(newInstance)) { if (newInstance) alert('Invalid instance'); return; } if (newInstance) { newInstance = newInstance.toLowerCase().trim(); // navigate(isLocal ? `/${newInstance}/p/l` : `/${newInstance}/p`); location.hash = isLocal ? `/${newInstance}/p/l` : `/${newInstance}/p`; } }} > Go to another instance… {currentInstance !== instance && ( { location.hash = isLocal ? `/${currentInstance}/p/l` : `/${currentInstance}/p`; }} > {' '} Go to my instance ({currentInstance}) )} } /> ); } export default Public;