Fix more type errors
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -153,7 +153,7 @@ const Progress: React.FC<FixProgress> = ({ completed, total }) => (
|
||||
);
|
||||
|
||||
interface OptionsFormProps {
|
||||
step: Step;
|
||||
step: Step | undefined;
|
||||
onSubmit: (values: FormValues) => Promise<void>;
|
||||
onClose: () => void;
|
||||
}
|
||||
@@ -226,7 +226,7 @@ const OptionsForm: React.FC<OptionsFormProps> = ({
|
||||
};
|
||||
|
||||
interface FooterProps {
|
||||
step: Step;
|
||||
step: Step | undefined;
|
||||
onSubmit: () => void;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
@@ -324,8 +324,8 @@ const SubscriptionStatus: React.FC<SubscriptionStatusProps> = ({
|
||||
return true;
|
||||
}, [userDetails]);
|
||||
|
||||
const handleClick = useMemo(() => {
|
||||
const eventHandler: MouseEventHandler<HTMLSpanElement> = (e) => {
|
||||
const handleClick: MouseEventHandler<HTMLSpanElement> = useCallback(
|
||||
(e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
if (isSubscriptionActive(userDetails.subscription)) {
|
||||
@@ -342,9 +342,9 @@ const SubscriptionStatus: React.FC<SubscriptionStatusProps> = ({
|
||||
onShowPlanSelector();
|
||||
}
|
||||
}
|
||||
};
|
||||
return eventHandler;
|
||||
}, [userDetails]);
|
||||
},
|
||||
[userDetails],
|
||||
);
|
||||
|
||||
if (!hasAMessage) {
|
||||
return <></>;
|
||||
@@ -387,8 +387,8 @@ const SubscriptionStatus: React.FC<SubscriptionStatusProps> = ({
|
||||
<Box sx={{ px: 1, pt: 0.5 }}>
|
||||
<Typography
|
||||
variant="small"
|
||||
onClick={handleClick && handleClick}
|
||||
sx={{ color: "text.muted", cursor: handleClick && "pointer" }}
|
||||
onClick={handleClick}
|
||||
sx={{ color: "text.muted" }}
|
||||
>
|
||||
{message}
|
||||
</Typography>
|
||||
|
||||
@@ -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,
|
||||
)!
|
||||
)
|
||||
}
|
||||
/>
|
||||
<DownloadStatusNotifications
|
||||
@@ -1082,7 +1082,7 @@ const Page: React.FC = () => {
|
||||
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 ? (
|
||||
<PeopleEmptyState />
|
||||
) : (
|
||||
@@ -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(",");
|
||||
};
|
||||
|
||||
@@ -284,7 +284,7 @@ const DesktopBox = styled(CenteredRow)`
|
||||
|
||||
const Slideshow: React.FC = () => {
|
||||
const [selectedIndex, setSelectedIndex] = useState(0);
|
||||
const containerRef = useRef<HTMLDivElement | undefined>(undefined);
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const intervalID = setInterval(() => {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -62,7 +62,7 @@ export const useFileInput = ({
|
||||
onSelect,
|
||||
onCancel,
|
||||
}: UseFileInputParams): UseFileInputResult => {
|
||||
const inputRef = useRef<HTMLInputElement | undefined>(undefined);
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// React (as of 19) doesn't support attaching the onCancel event handler
|
||||
|
||||
@@ -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<Omit<SearchBarProps, "onShowSearchInput">> = ({
|
||||
onSelectPeople();
|
||||
};
|
||||
|
||||
const handleSelectPerson = (personID: string | undefined) => {
|
||||
const handleSelectPerson = (personID: string) => {
|
||||
resetSearch();
|
||||
onSelectPerson(personID);
|
||||
};
|
||||
|
||||
@@ -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<Collection | undefined> =>
|
||||
): Promise<Collection> =>
|
||||
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).
|
||||
|
||||
@@ -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<LoadingBarRef | undefined>(undefined);
|
||||
const loadingBarRef = useRef<LoadingBarRef | null>(null);
|
||||
|
||||
const showLoadingBar = useCallback(() => {
|
||||
loadingBarRef.current?.continuousStart();
|
||||
|
||||
Reference in New Issue
Block a user