this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Prevent re-render timeline in multi-column mode

+37 -24
+5 -1
src/components/columns.jsx
··· 18 18 const snapStates = useSnapshot(states); 19 19 const { shortcuts } = snapStates; 20 20 21 + console.debug('RENDER Columns', shortcuts); 22 + 21 23 const components = shortcuts.map((shortcut) => { 22 24 if (!shortcut) return null; 23 25 const { type, ...params } = shortcut; ··· 33 35 trending: Trending, 34 36 }[type]; 35 37 if (!Component) return null; 36 - return <Component {...params} />; 38 + return ( 39 + <Component key={type + JSON.stringify(params)} {...params} columnMode /> 40 + ); 37 41 }); 38 42 39 43 useHotkeys(['1', '2', '3', '4', '5', '6', '7', '8', '9'], (e, handler) => {
+11 -8
src/pages/hashtag.jsx
··· 25 25 const TAGS_LIMIT_PER_MODE = 4; 26 26 const TOTAL_TAGS_LIMIT = TAGS_LIMIT_PER_MODE + 1; 27 27 28 - function Hashtags(props) { 29 - const navigate = useNavigate(); 30 - let { hashtag, ...params } = useParams(); 28 + function Hashtags({ columnMode, ...props }) { 29 + // const navigate = useNavigate(); 30 + let { hashtag, ...params } = columnMode ? {} : useParams(); 31 31 if (props.hashtag) hashtag = props.hashtag; 32 32 let hashtags = hashtag.trim().split(/[\s+]+/); 33 33 hashtags.sort(); ··· 217 217 ) { 218 218 hashtags.push(newHashtag); 219 219 hashtags.sort(); 220 - navigate( 221 - instance 222 - ? `/${instance}/t/${hashtags.join('+')}` 223 - : `/t/${hashtags.join('+')}`, 224 - ); 220 + // navigate( 221 + // instance 222 + // ? `/${instance}/t/${hashtags.join('+')}` 223 + // : `/t/${hashtags.join('+')}`, 224 + // ); 225 + location.hash = instance 226 + ? `/${instance}/t/${hashtags.join('+')}` 227 + : `/t/${hashtags.join('+')}`; 225 228 } 226 229 }} 227 230 >
+3 -2
src/pages/list.jsx
··· 24 24 const snapStates = useSnapshot(states); 25 25 const { masto, instance } = api(); 26 26 const id = props?.id || useParams()?.id; 27 - const navigate = useNavigate(); 27 + // const navigate = useNavigate(); 28 28 const latestItem = useRef(); 29 29 // const [reloadCount, reload] = useReducer((c) => c + 1, 0); 30 30 ··· 154 154 setList(result.list); 155 155 // reload(); 156 156 } else if (result.state === 'deleted') { 157 - navigate('/l'); 157 + // navigate('/l'); 158 + location.hash = '/l'; 158 159 } 159 160 setShowListAddEditModal(false); 160 161 }}
+3 -2
src/pages/mentions.jsx
··· 8 8 import useTitle from '../utils/useTitle'; 9 9 10 10 const LIMIT = 20; 11 + const emptySearchParams = new URLSearchParams(); 11 12 12 - function Mentions(props) { 13 + function Mentions({ columnMode, ...props }) { 13 14 useTitle('Mentions', '/mentions'); 14 15 const { masto, instance } = api(); 15 - const [searchParams] = useSearchParams(); 16 + const [searchParams] = columnMode ? [emptySearchParams] : useSearchParams(); 16 17 const type = props?.type || searchParams.get('type'); 17 18 18 19 const mentionsIterator = useRef();
+7 -4
src/pages/public.jsx
··· 14 14 15 15 const LIMIT = 20; 16 16 17 - function Public({ local, ...props }) { 17 + function Public({ local, columnMode, ...props }) { 18 18 const snapStates = useSnapshot(states); 19 19 const isLocal = !!local; 20 - const params = useParams(); 20 + const params = columnMode ? {} : useParams(); 21 21 const { masto, instance } = api({ 22 22 instance: props?.instance || params.instance, 23 23 }); 24 24 const title = `${isLocal ? 'Local' : 'Federated'} timeline (${instance})`; 25 25 useTitle(title, isLocal ? `/:instance?/p/l` : `/:instance?/p`); 26 - const navigate = useNavigate(); 26 + // const navigate = useNavigate(); 27 27 const latestItem = useRef(); 28 28 29 29 const publicIterator = useRef(); ··· 128 128 } 129 129 if (newInstance) { 130 130 newInstance = newInstance.toLowerCase().trim(); 131 - navigate(isLocal ? `/${newInstance}/p/l` : `/${newInstance}/p`); 131 + // navigate(isLocal ? `/${newInstance}/p/l` : `/${newInstance}/p`); 132 + location.hash = isLocal 133 + ? `/${newInstance}/p/l` 134 + : `/${newInstance}/p`; 132 135 } 133 136 }} 134 137 >
+5 -4
src/pages/trending.jsx
··· 15 15 16 16 const LIMIT = 20; 17 17 18 - function Trending(props) { 18 + function Trending({ columnMode, ...props }) { 19 19 const snapStates = useSnapshot(states); 20 - const params = useParams(); 20 + const params = columnMode ? {} : useParams(); 21 21 const { masto, instance } = api({ 22 22 instance: props?.instance || params.instance, 23 23 }); 24 24 const title = `Trending (${instance})`; 25 25 useTitle(title, `/:instance?/trending`); 26 - const navigate = useNavigate(); 26 + // const navigate = useNavigate(); 27 27 const latestItem = useRef(); 28 28 29 29 const [hashtags, setHashtags] = useState([]); ··· 151 151 } 152 152 if (newInstance) { 153 153 newInstance = newInstance.toLowerCase().trim(); 154 - navigate(`/${newInstance}/trending`); 154 + // navigate(`/${newInstance}/trending`); 155 + location.hash = `/${newInstance}/trending`; 155 156 } 156 157 }} 157 158 >
+3 -3
src/utils/useTitle.js
··· 1 - import { useEffect } from 'preact/hooks'; 1 + import { useLayoutEffect } from 'preact/hooks'; 2 2 import { matchPath } from 'react-router-dom'; 3 3 import { subscribeKey } from 'valtio/utils'; 4 4 ··· 23 23 } else if (path) { 24 24 matched = matchPath(path, currentLocation); 25 25 } 26 - console.log('setTitle', { title, path, currentLocation, paths, matched }); 26 + console.debug('setTitle', { title, path, currentLocation, paths, matched }); 27 27 if (matched) { 28 28 document.title = title ? `${title} / ${CLIENT_NAME}` : CLIENT_NAME; 29 29 } 30 30 } 31 31 32 - useEffect(() => { 32 + useLayoutEffect(() => { 33 33 setTitle(); 34 34 return subscribeKey(states, 'currentLocation', setTitle); 35 35 }, [title, path]);