From 995a35cd76777ba9de6355d16dcd12e99a9136ac Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 15 Jun 2021 11:57:26 +1000 Subject: [PATCH] interface: improve memoization and event listening of components --- pkg/interface/src/views/components/GroupLink.tsx | 7 ++++--- pkg/interface/src/views/components/ProfileOverlay.tsx | 10 ++++++---- pkg/interface/src/views/components/RemoteContent.tsx | 5 +++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/pkg/interface/src/views/components/GroupLink.tsx b/pkg/interface/src/views/components/GroupLink.tsx index 7a697ff889..417302f500 100644 --- a/pkg/interface/src/views/components/GroupLink.tsx +++ b/pkg/interface/src/views/components/GroupLink.tsx @@ -1,5 +1,5 @@ import { Box, Col, Icon, Row, Text } from '@tlon/indigo-react'; -import React, { ReactElement } from 'react'; +import React, { ReactElement, useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import { useModal } from '~/logic/lib/useModal'; import useMetadataState, { usePreview } from '~/logic/state/metadata'; @@ -15,9 +15,10 @@ export function GroupLink( ): ReactElement { const { resource, ...rest } = props; const name = resource.slice(6); - const associations = useMetadataState(state => state.associations); + const joined = useMetadataState( + useCallback(s => resource in s.associations.groups, [resource]) + ); const history = useHistory(); - const joined = resource in associations.groups; const { modal, showModal } = useModal({ modal: diff --git a/pkg/interface/src/views/components/ProfileOverlay.tsx b/pkg/interface/src/views/components/ProfileOverlay.tsx index 2eb7e5baba..803b124f9f 100644 --- a/pkg/interface/src/views/components/ProfileOverlay.tsx +++ b/pkg/interface/src/views/components/ProfileOverlay.tsx @@ -9,6 +9,7 @@ import { Text } from '@tlon/indigo-react'; import { cite, uxToHex } from '@urbit/api'; +import shallow from 'zustand/shallow'; import _ from 'lodash'; import React, { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useHistory } from 'react-router-dom'; @@ -20,7 +21,7 @@ import { useCopy } from '~/logic/lib/useCopy'; import { useOutsideClick } from '~/logic/lib/useOutsideClick'; import { useShowNickname } from '~/logic/lib/util'; import { useContact } from '~/logic/state/contact'; -import useSettingsState from '~/logic/state/settings'; +import useSettingsState, { SettingsState } from '~/logic/state/settings'; import { Portal } from './Portal'; import { ProfileStatus } from './ProfileStatus'; import RichText from './RichText'; @@ -40,6 +41,8 @@ type ProfileOverlayProps = BoxProps & { color?: string; }; +const selSettings = (s: SettingsState) => [s.calm.hideAvatars, s.calm.hideNicknames]; + const ProfileOverlay = (props: ProfileOverlayProps) => { const { ship, @@ -53,8 +56,7 @@ const ProfileOverlay = (props: ProfileOverlayProps) => { const history = useHistory(); const outerRef = useRef(null); const innerRef = useRef(null); - const hideAvatars = useSettingsState(state => state.calm.hideAvatars); - const hideNicknames = useSettingsState(state => state.calm.hideNicknames); + const [hideAvatars, hideNicknames] = useSettingsState(selSettings, shallow); const isOwn = useMemo(() => window.ship === ship, [ship]); const { copyDisplay, doCopy, didCopy } = useCopy(`~${ship}`); @@ -128,7 +130,7 @@ const ProfileOverlay = (props: ProfileOverlayProps) => { return ( - + {children} { open && ( diff --git a/pkg/interface/src/views/components/RemoteContent.tsx b/pkg/interface/src/views/components/RemoteContent.tsx index 455b8072ae..0ace832438 100644 --- a/pkg/interface/src/views/components/RemoteContent.tsx +++ b/pkg/interface/src/views/components/RemoteContent.tsx @@ -47,6 +47,7 @@ class RemoteContent extends Component { private fetchController: AbortController | undefined; containerRef: HTMLDivElement | null = null; private saving = false; + private isOembed = false; constructor(props) { super(props); this.state = { @@ -60,6 +61,7 @@ class RemoteContent extends Component { this.wrapInLink = this.wrapInLink.bind(this); this.onError = this.onError.bind(this); this.toggleArrow = this.toggleArrow.bind(this); + this.isOembed = hasProvider(props.url); } save = () => { @@ -204,7 +206,6 @@ return; const isImage = IMAGE_REGEX.test(url); const isAudio = AUDIO_REGEX.test(url); const isVideo = VIDEO_REGEX.test(url); - const isOembed = hasProvider(url); const isTranscluded = () => { return transcluded; @@ -315,7 +316,7 @@ return; : null} ); - } else if (isOembed && remoteContentPolicy.oembedShown) { + } else if (this.isOembed && remoteContentPolicy.oembedShown) { if (!this.state.embed || this.state.embed?.html === '') { this.loadOembed(); }