From 6a5e0122368897a700c987d2828c42c09d774a7a Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Mon, 7 Jul 2025 17:11:57 +0530 Subject: [PATCH] Fix more type errors --- .../Collections/GalleryBarAndListHeader.tsx | 2 +- .../photos/src/components/FixCreationTime.tsx | 4 +-- web/apps/photos/src/components/Sidebar.tsx | 14 ++++---- web/apps/photos/src/pages/gallery.tsx | 36 +++++++++---------- web/apps/photos/src/pages/index.tsx | 2 +- web/apps/photos/src/utils/file/index.ts | 2 +- .../components/utils/use-file-input.ts | 2 +- .../new/photos/components/SearchBar.tsx | 4 +-- .../new/photos/components/gallery/helpers.ts | 19 +++++++--- .../components/utils/use-loading-bar.ts | 2 +- 10 files changed, 48 insertions(+), 39 deletions(-) diff --git a/web/apps/photos/src/components/Collections/GalleryBarAndListHeader.tsx b/web/apps/photos/src/components/Collections/GalleryBarAndListHeader.tsx index 514abab78b..96b36a5a02 100644 --- a/web/apps/photos/src/components/Collections/GalleryBarAndListHeader.tsx +++ b/web/apps/photos/src/components/Collections/GalleryBarAndListHeader.tsx @@ -284,7 +284,7 @@ const compareCollectionsLatestFile = ( return -1; } else { const sortedFiles = sortFiles([first, second]); - if (sortedFiles[0].id !== first.id) { + if (sortedFiles[0]?.id !== first.id) { return 1; } else { return -1; diff --git a/web/apps/photos/src/components/FixCreationTime.tsx b/web/apps/photos/src/components/FixCreationTime.tsx index 62a578a6c1..4dfe1d2cc4 100644 --- a/web/apps/photos/src/components/FixCreationTime.tsx +++ b/web/apps/photos/src/components/FixCreationTime.tsx @@ -153,7 +153,7 @@ const Progress: React.FC = ({ completed, total }) => ( ); interface OptionsFormProps { - step: Step; + step: Step | undefined; onSubmit: (values: FormValues) => Promise; onClose: () => void; } @@ -226,7 +226,7 @@ const OptionsForm: React.FC = ({ }; interface FooterProps { - step: Step; + step: Step | undefined; onSubmit: () => void; onClose: () => void; } diff --git a/web/apps/photos/src/components/Sidebar.tsx b/web/apps/photos/src/components/Sidebar.tsx index 082f48e9dd..eeb8a1f2ca 100644 --- a/web/apps/photos/src/components/Sidebar.tsx +++ b/web/apps/photos/src/components/Sidebar.tsx @@ -324,8 +324,8 @@ const SubscriptionStatus: React.FC = ({ return true; }, [userDetails]); - const handleClick = useMemo(() => { - const eventHandler: MouseEventHandler = (e) => { + const handleClick: MouseEventHandler = useCallback( + (e) => { e.stopPropagation(); if (isSubscriptionActive(userDetails.subscription)) { @@ -342,9 +342,9 @@ const SubscriptionStatus: React.FC = ({ onShowPlanSelector(); } } - }; - return eventHandler; - }, [userDetails]); + }, + [userDetails], + ); if (!hasAMessage) { return <>; @@ -387,8 +387,8 @@ const SubscriptionStatus: React.FC = ({ {message} diff --git a/web/apps/photos/src/pages/gallery.tsx b/web/apps/photos/src/pages/gallery.tsx index 3cbaaf12ac..949b6e43a4 100644 --- a/web/apps/photos/src/pages/gallery.tsx +++ b/web/apps/photos/src/pages/gallery.tsx @@ -671,7 +671,8 @@ const Page: React.FC = () => { filteredFiles, ); const userFiles = selectedFiles.filter( - (f) => f.ownerID == user.id, + // If a selection is happening, there must be a user. + (f) => f.ownerID == user!.id, ); const sourceCollectionID = selected.collectionID; if (userFiles.length > 0) { @@ -735,7 +736,8 @@ const Page: React.FC = () => { op == "download" ? selectedFiles : selectedFiles.filter( - (file) => file.ownerID == user.id, + // There'll be a user if files are being selected. + (file) => file.ownerID == user!.id, ); if (toProcessFiles.length > 0) { await performFileOp( @@ -772,24 +774,24 @@ const Page: React.FC = () => { const handleSelectSearchOption = ( searchOption: SearchOption | undefined, ) => { - const type = searchOption?.suggestion.type; - if (type == "collection" || type == "person") { + if (searchOption) { + const type = searchOption.suggestion.type; if (type == "collection") { dispatch({ type: "showCollectionSummary", collectionSummaryID: searchOption.suggestion.collectionID, }); - } else { + } else if (type == "person") { dispatch({ type: "showPerson", personID: searchOption.suggestion.person.id, }); + } else { + dispatch({ + type: "enterSearchMode", + searchSuggestion: searchOption.suggestion, + }); } - } else if (searchOption) { - dispatch({ - type: "enterSearchMode", - searchSuggestion: searchOption.suggestion, - }); } else { dispatch({ type: "exitSearch" }); } @@ -914,12 +916,13 @@ const Page: React.FC = () => { // 3. The caller (eventually) triggers a remote pull in the // background, but meanwhile uses this updated metadata. // - // TODO(RE): Replace with file fetch? + // TODO: Replace with files pull? dispatch({ type: "unsyncedPrivateMagicMetadataUpdate", fileID, privateMagicMetadata: { ...file.magicMetadata, + count: file.magicMetadata?.count ?? 0, version: (file.magicMetadata?.version ?? 0) + 1, data: { ...file.magicMetadata?.data, visibility }, }, @@ -992,13 +995,10 @@ const Page: React.FC = () => { attributes={collectionSelectorAttributes} collectionSummaries={normalCollectionSummaries} collectionForCollectionSummaryID={(id) => - // Null assert since the collection selector should only - // show "selectable" normalCollectionSummaries. See: - // [Note: Picking from selectable collection summaries]. findCollectionCreatingUncategorizedIfNeeded( state.collections, id, - )! + ) } /> { emailByUserID={state.emailByUserID} shareSuggestionEmails={state.shareSuggestionEmails} people={ - (state.view.type == "people" + (state?.view?.type == "people" ? state.view.visiblePeople : undefined) ?? [] } @@ -1140,7 +1140,7 @@ const Page: React.FC = () => { /> ) : !isInSearchMode && !isFirstLoad && - state.view.type == "people" && + state?.view?.type == "people" && !state.view.activePerson ? ( ) : ( @@ -1225,7 +1225,7 @@ const OfflineMessage: React.FC = () => ( * Preload all three variants of a responsive image. */ const preloadImage = (imgBasePath: string) => { - const srcset = []; + const srcset: string[] = []; for (let i = 1; i <= 3; i++) srcset.push(`${imgBasePath}/${i}x.png ${i}x`); new Image().srcset = srcset.join(","); }; diff --git a/web/apps/photos/src/pages/index.tsx b/web/apps/photos/src/pages/index.tsx index d452129a18..d276aad67b 100644 --- a/web/apps/photos/src/pages/index.tsx +++ b/web/apps/photos/src/pages/index.tsx @@ -284,7 +284,7 @@ const DesktopBox = styled(CenteredRow)` const Slideshow: React.FC = () => { const [selectedIndex, setSelectedIndex] = useState(0); - const containerRef = useRef(undefined); + const containerRef = useRef(null); useEffect(() => { const intervalID = setInterval(() => { diff --git a/web/apps/photos/src/utils/file/index.ts b/web/apps/photos/src/utils/file/index.ts index aefa842787..326cfc7ad1 100644 --- a/web/apps/photos/src/utils/file/index.ts +++ b/web/apps/photos/src/utils/file/index.ts @@ -18,7 +18,7 @@ export interface SelectedState { [k: number]: boolean; ownCount: number; count: number; - collectionID: number; + collectionID: number | undefined; /** * The context in which the selection was made. Only set by newer code if * there is an active selection (older code continues to rely on the diff --git a/web/packages/gallery/components/utils/use-file-input.ts b/web/packages/gallery/components/utils/use-file-input.ts index 7aec8d3d6e..a137b34ad3 100644 --- a/web/packages/gallery/components/utils/use-file-input.ts +++ b/web/packages/gallery/components/utils/use-file-input.ts @@ -62,7 +62,7 @@ export const useFileInput = ({ onSelect, onCancel, }: UseFileInputParams): UseFileInputResult => { - const inputRef = useRef(undefined); + const inputRef = useRef(null); useEffect(() => { // React (as of 19) doesn't support attaching the onCancel event handler diff --git a/web/packages/new/photos/components/SearchBar.tsx b/web/packages/new/photos/components/SearchBar.tsx index f242aee020..2c97d044ec 100644 --- a/web/packages/new/photos/components/SearchBar.tsx +++ b/web/packages/new/photos/components/SearchBar.tsx @@ -83,7 +83,7 @@ export interface SearchBarProps { /** * Called when the user selects a person shown in the empty state view. */ - onSelectPerson: (personID: string | undefined) => void; + onSelectPerson: (personID: string) => void; } /** @@ -210,7 +210,7 @@ const SearchInput: React.FC> = ({ onSelectPeople(); }; - const handleSelectPerson = (personID: string | undefined) => { + const handleSelectPerson = (personID: string) => { resetSearch(); onSelectPerson(personID); }; diff --git a/web/packages/new/photos/components/gallery/helpers.ts b/web/packages/new/photos/components/gallery/helpers.ts index b3d69197fc..749393ad08 100644 --- a/web/packages/new/photos/components/gallery/helpers.ts +++ b/web/packages/new/photos/components/gallery/helpers.ts @@ -46,17 +46,26 @@ export const validateKey = async () => { /** * Return the {@link Collection} (from amongst {@link collections}) with the - * given {@link collectionSummaryID}. As a special case, if the given - * {@link collectionSummaryID} is the ID of the placeholder uncategorized - * collection, create a new uncategorized collection and then return it. + * given {@link collectionSummaryID}. + * + * As a special case, if the given {@link collectionSummaryID} is the ID of the + * placeholder uncategorized collection, create a new uncategorized collection + * and then return it. + * + * This is used in the context of the collection summary, so one of the two + * cases must be true. */ export const findCollectionCreatingUncategorizedIfNeeded = async ( collections: Collection[], collectionSummaryID: number, -): Promise => +): Promise => collectionSummaryID == PseudoCollectionID.uncategorizedPlaceholder ? createUncategorizedCollection() - : collections.find(({ id }) => id == collectionSummaryID); + : // Null assert since the collection selector should only + // show "selectable" normalCollectionSummaries. + // + // See: [Note: Picking from selectable collection summaries]. + collections.find(({ id }) => id == collectionSummaryID)!; /** * Perform a "collection operation" on the selected file(s). diff --git a/web/packages/new/photos/components/utils/use-loading-bar.ts b/web/packages/new/photos/components/utils/use-loading-bar.ts index 6297443e73..c5c7152fed 100644 --- a/web/packages/new/photos/components/utils/use-loading-bar.ts +++ b/web/packages/new/photos/components/utils/use-loading-bar.ts @@ -12,7 +12,7 @@ import { type LoadingBarRef } from "react-top-loading-bar"; * loading bar. This hook returns these functions (and the ref). */ export const useLoadingBar = () => { - const loadingBarRef = useRef(undefined); + const loadingBarRef = useRef(null); const showLoadingBar = useCallback(() => { loadingBarRef.current?.continuousStart();