Prevent re-render timeline in multi-column mode

This commit is contained in:
Lim Chee Aun 2023-07-05 16:59:28 +08:00
parent e6880859ee
commit 2eba4eaf59
7 changed files with 37 additions and 24 deletions

View file

@ -18,6 +18,8 @@ function Columns() {
const snapStates = useSnapshot(states); const snapStates = useSnapshot(states);
const { shortcuts } = snapStates; const { shortcuts } = snapStates;
console.debug('RENDER Columns', shortcuts);
const components = shortcuts.map((shortcut) => { const components = shortcuts.map((shortcut) => {
if (!shortcut) return null; if (!shortcut) return null;
const { type, ...params } = shortcut; const { type, ...params } = shortcut;
@ -33,7 +35,9 @@ function Columns() {
trending: Trending, trending: Trending,
}[type]; }[type];
if (!Component) return null; if (!Component) return null;
return <Component {...params} />; return (
<Component key={type + JSON.stringify(params)} {...params} columnMode />
);
}); });
useHotkeys(['1', '2', '3', '4', '5', '6', '7', '8', '9'], (e, handler) => { useHotkeys(['1', '2', '3', '4', '5', '6', '7', '8', '9'], (e, handler) => {

View file

@ -25,9 +25,9 @@ const LIMIT = 20;
const TAGS_LIMIT_PER_MODE = 4; const TAGS_LIMIT_PER_MODE = 4;
const TOTAL_TAGS_LIMIT = TAGS_LIMIT_PER_MODE + 1; const TOTAL_TAGS_LIMIT = TAGS_LIMIT_PER_MODE + 1;
function Hashtags(props) { function Hashtags({ columnMode, ...props }) {
const navigate = useNavigate(); // const navigate = useNavigate();
let { hashtag, ...params } = useParams(); let { hashtag, ...params } = columnMode ? {} : useParams();
if (props.hashtag) hashtag = props.hashtag; if (props.hashtag) hashtag = props.hashtag;
let hashtags = hashtag.trim().split(/[\s+]+/); let hashtags = hashtag.trim().split(/[\s+]+/);
hashtags.sort(); hashtags.sort();
@ -217,11 +217,14 @@ function Hashtags(props) {
) { ) {
hashtags.push(newHashtag); hashtags.push(newHashtag);
hashtags.sort(); hashtags.sort();
navigate( // navigate(
instance // instance
? `/${instance}/t/${hashtags.join('+')}` // ? `/${instance}/t/${hashtags.join('+')}`
: `/t/${hashtags.join('+')}`, // : `/t/${hashtags.join('+')}`,
); // );
location.hash = instance
? `/${instance}/t/${hashtags.join('+')}`
: `/t/${hashtags.join('+')}`;
} }
}} }}
> >

View file

@ -24,7 +24,7 @@ function List(props) {
const snapStates = useSnapshot(states); const snapStates = useSnapshot(states);
const { masto, instance } = api(); const { masto, instance } = api();
const id = props?.id || useParams()?.id; const id = props?.id || useParams()?.id;
const navigate = useNavigate(); // const navigate = useNavigate();
const latestItem = useRef(); const latestItem = useRef();
// const [reloadCount, reload] = useReducer((c) => c + 1, 0); // const [reloadCount, reload] = useReducer((c) => c + 1, 0);
@ -154,7 +154,8 @@ function List(props) {
setList(result.list); setList(result.list);
// reload(); // reload();
} else if (result.state === 'deleted') { } else if (result.state === 'deleted') {
navigate('/l'); // navigate('/l');
location.hash = '/l';
} }
setShowListAddEditModal(false); setShowListAddEditModal(false);
}} }}

View file

@ -8,11 +8,12 @@ import { saveStatus } from '../utils/states';
import useTitle from '../utils/useTitle'; import useTitle from '../utils/useTitle';
const LIMIT = 20; const LIMIT = 20;
const emptySearchParams = new URLSearchParams();
function Mentions(props) { function Mentions({ columnMode, ...props }) {
useTitle('Mentions', '/mentions'); useTitle('Mentions', '/mentions');
const { masto, instance } = api(); const { masto, instance } = api();
const [searchParams] = useSearchParams(); const [searchParams] = columnMode ? [emptySearchParams] : useSearchParams();
const type = props?.type || searchParams.get('type'); const type = props?.type || searchParams.get('type');
const mentionsIterator = useRef(); const mentionsIterator = useRef();

View file

@ -14,16 +14,16 @@ import useTitle from '../utils/useTitle';
const LIMIT = 20; const LIMIT = 20;
function Public({ local, ...props }) { function Public({ local, columnMode, ...props }) {
const snapStates = useSnapshot(states); const snapStates = useSnapshot(states);
const isLocal = !!local; const isLocal = !!local;
const params = useParams(); const params = columnMode ? {} : useParams();
const { masto, instance } = api({ const { masto, instance } = api({
instance: props?.instance || params.instance, instance: props?.instance || params.instance,
}); });
const title = `${isLocal ? 'Local' : 'Federated'} timeline (${instance})`; const title = `${isLocal ? 'Local' : 'Federated'} timeline (${instance})`;
useTitle(title, isLocal ? `/:instance?/p/l` : `/:instance?/p`); useTitle(title, isLocal ? `/:instance?/p/l` : `/:instance?/p`);
const navigate = useNavigate(); // const navigate = useNavigate();
const latestItem = useRef(); const latestItem = useRef();
const publicIterator = useRef(); const publicIterator = useRef();
@ -128,7 +128,10 @@ function Public({ local, ...props }) {
} }
if (newInstance) { if (newInstance) {
newInstance = newInstance.toLowerCase().trim(); newInstance = newInstance.toLowerCase().trim();
navigate(isLocal ? `/${newInstance}/p/l` : `/${newInstance}/p`); // navigate(isLocal ? `/${newInstance}/p/l` : `/${newInstance}/p`);
location.hash = isLocal
? `/${newInstance}/p/l`
: `/${newInstance}/p`;
} }
}} }}
> >

View file

@ -15,15 +15,15 @@ import useTitle from '../utils/useTitle';
const LIMIT = 20; const LIMIT = 20;
function Trending(props) { function Trending({ columnMode, ...props }) {
const snapStates = useSnapshot(states); const snapStates = useSnapshot(states);
const params = useParams(); const params = columnMode ? {} : useParams();
const { masto, instance } = api({ const { masto, instance } = api({
instance: props?.instance || params.instance, instance: props?.instance || params.instance,
}); });
const title = `Trending (${instance})`; const title = `Trending (${instance})`;
useTitle(title, `/:instance?/trending`); useTitle(title, `/:instance?/trending`);
const navigate = useNavigate(); // const navigate = useNavigate();
const latestItem = useRef(); const latestItem = useRef();
const [hashtags, setHashtags] = useState([]); const [hashtags, setHashtags] = useState([]);
@ -151,7 +151,8 @@ function Trending(props) {
} }
if (newInstance) { if (newInstance) {
newInstance = newInstance.toLowerCase().trim(); newInstance = newInstance.toLowerCase().trim();
navigate(`/${newInstance}/trending`); // navigate(`/${newInstance}/trending`);
location.hash = `/${newInstance}/trending`;
} }
}} }}
> >

View file

@ -1,4 +1,4 @@
import { useEffect } from 'preact/hooks'; import { useLayoutEffect } from 'preact/hooks';
import { matchPath } from 'react-router-dom'; import { matchPath } from 'react-router-dom';
import { subscribeKey } from 'valtio/utils'; import { subscribeKey } from 'valtio/utils';
@ -23,13 +23,13 @@ export default function useTitle(title, path) {
} else if (path) { } else if (path) {
matched = matchPath(path, currentLocation); matched = matchPath(path, currentLocation);
} }
console.log('setTitle', { title, path, currentLocation, paths, matched }); console.debug('setTitle', { title, path, currentLocation, paths, matched });
if (matched) { if (matched) {
document.title = title ? `${title} / ${CLIENT_NAME}` : CLIENT_NAME; document.title = title ? `${title} / ${CLIENT_NAME}` : CLIENT_NAME;
} }
} }
useEffect(() => { useLayoutEffect(() => {
setTitle(); setTitle();
return subscribeKey(states, 'currentLocation', setTitle); return subscribeKey(states, 'currentLocation', setTitle);
}, [title, path]); }, [title, path]);