feat(settings): search across all settings (#453 phase 3) #467

Merged
jared merged 2 commits from feat/settings-search into lotus 2026-10-25 19:38:23 -04:00
2 changed files with 35 additions and 1 deletions
Showing only changes of commit 02bd356a89 - Show all commits
@@ -33,6 +33,7 @@ import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
import { ModalWide } from '../../../styles/Modal.css';
import { validBlurHash } from '../../../utils/blurHash';
import { useNearViewport } from '../../../hooks/useNearViewport';
import { whenMediaAuthReady } from '../../../../sw-session';
type RenderViewerProps = {
src: string;
@@ -115,13 +116,24 @@ export const ImageContent = as<'div', ImageContentProps>(
const handleLoad = () => {
setLoad(true);
};
// An image requested before the service worker controls the page goes out
// without the access token and fails (first visit, just after an update).
// Retry once by itself when that's ready; only then offer "Retry".
const [attempt, setAttempt] = useState(0);
const autoRetried = useRef(false);
const handleError = () => {
setLoad(false);
if (!autoRetried.current && !encInfo) {
autoRetried.current = true;
whenMediaAuthReady().then(() => setAttempt((n) => n + 1));
return;
}
setError(true);
};
const handleRetry = () => {
setError(false);
setAttempt((n) => n + 1);
loadSrc();
};
@@ -182,7 +194,7 @@ export const ImageContent = as<'div', ImageContentProps>(
</Box>
)}
{srcState.status === AsyncStatus.Success && (
<Box className={classNames(css.AbsoluteContainer, blurred && css.Blur)}>
<Box key={attempt} className={classNames(css.AbsoluteContainer, blurred && css.Blur)}>
{renderImage({
alt: body,
title: body,
+22
View File
@@ -9,3 +9,25 @@ export function pushSessionToSW(baseUrl?: string, accessToken?: string, userId?:
userId,
});
}
/**
* Resolves once media requests can carry the session: immediately-ish when a
* service worker already controls the page, otherwise when one takes control
* (first visit / just updated) or after `timeoutMs`. Used to retry a media
* load that raced the worker's activation and went out without a token.
*/
export function whenMediaAuthReady(timeoutMs = 3000): Promise<void> {
return new Promise((resolve) => {
const sw = 'serviceWorker' in navigator ? navigator.serviceWorker : undefined;
if (!sw || sw.controller) {
window.setTimeout(resolve, 500);
return;
}
const done = () => {
sw.removeEventListener('controllerchange', done);
resolve();
};
sw.addEventListener('controllerchange', done);
window.setTimeout(done, timeoutMs);
});
}