From 7d866404b3d98e428679481424fb5d0412cec96e Mon Sep 17 00:00:00 2001 From: litruv Date: Sun, 23 Aug 2026 16:18:35 +1000 Subject: [PATCH] Fix Android updates dialog, mobile About page, and user color crash guard. Use stripBase for update static copy paths, show Settings detail on mobile when nav is hidden, pause Settings focus trap during release notes, and guard extractMemberColorPreference when room is not a Matrix Room instance. --- index.html | 6 ++++++ src/app/components/Modal500.tsx | 4 ++++ src/app/components/page/Page.tsx | 3 ++- src/app/components/updates-dialog/UpdatesDialog.tsx | 6 +++++- src/app/features/settings/about/About.tsx | 5 +++-- src/app/utils/profileFields.ts | 2 +- vite.config.js | 3 ++- 7 files changed, 23 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index 3d1d48b..0f482d2 100644 --- a/index.html +++ b/index.html @@ -96,6 +96,12 @@
+ diff --git a/src/app/components/Modal500.tsx b/src/app/components/Modal500.tsx index a289650..7ab494a 100644 --- a/src/app/components/Modal500.tsx +++ b/src/app/components/Modal500.tsx @@ -1,7 +1,9 @@ import React, { ReactNode, useCallback, useState } from 'react'; import FocusTrap from 'focus-trap-react'; +import { useAtomValue } from 'jotai'; import { Modal, Overlay, OverlayBackdrop, OverlayCenter, PopOutContainerProvider } from 'folds'; import { stopPropagation } from '../utils/keyboard'; +import { releaseNotesDialogAtom } from '../state/releaseNotes'; type Modal500Props = { requestClose: () => void; @@ -10,11 +12,13 @@ type Modal500Props = { export function Modal500({ requestClose, children }: Modal500Props) { const [modalEl, setModalEl] = useState(null); const modalRef = useCallback((el: HTMLDivElement | null) => setModalEl(el), []); + const releaseNotesOpen = useAtomValue(releaseNotesDialogAtom).open; return ( }> @@ -23,7 +24,7 @@ export function PageRoot({ nav, children }: PageRootProps) { {screenSize !== ScreenSize.Mobile && ( )} - {!showCompactMaster && children} + {showDetail && children} ); } diff --git a/src/app/components/updates-dialog/UpdatesDialog.tsx b/src/app/components/updates-dialog/UpdatesDialog.tsx index feecb10..163d49f 100644 --- a/src/app/components/updates-dialog/UpdatesDialog.tsx +++ b/src/app/components/updates-dialog/UpdatesDialog.tsx @@ -12,6 +12,7 @@ import { Scroll, Spinner, Text, + usePopOutContainer, } from 'folds'; import { Icon, Icons } from '../icons'; import { stopPropagation } from '../../utils/keyboard'; @@ -36,6 +37,7 @@ export function UpdatesDialog({ onClose, }: UpdatesDialogProps) { const [showOlderList, setShowOlderList] = useState(false); + const popOutContainer = usePopOutContainer(); const displayVersion = activeDoc?.version; const displayTitle = activeDoc?.title ?? (displayVersion ? `Version ${displayVersion}` : 'Release notes'); @@ -48,7 +50,9 @@ export function UpdatesDialog({ }; const portalTarget = - document.getElementById('portalContainer') ?? document.body; + popOutContainer ?? + document.getElementById('portalContainer') ?? + document.body; return createPortal(
diff --git a/src/app/features/settings/about/About.tsx b/src/app/features/settings/about/About.tsx index 59d98c4..16dde6d 100644 --- a/src/app/features/settings/about/About.tsx +++ b/src/app/features/settings/about/About.tsx @@ -21,6 +21,9 @@ export function About({ requestClose }: AboutProps) { const [version, setVersion] = useState(''); const [protocolStatus, setProtocolStatus] = useState('Checking desktop protocol integration...'); const [protocolBusy, setProtocolBusy] = useState(false); + const [updatePreview, setUpdatePreview] = useState<{ title: string; description: string } | null>( + null + ); const formatProtocolStatus = useCallback((data: { scheme: string; @@ -101,8 +104,6 @@ export function About({ requestClose }: AboutProps) { getCurrentUpdatePreview().then(setUpdatePreview).catch(() => setUpdatePreview(null)); }, [refreshProtocolStatus]); - const [updatePreview, setUpdatePreview] = useState<{ title: string; description: string } | null>(null); - return ( diff --git a/src/app/utils/profileFields.ts b/src/app/utils/profileFields.ts index 40001de..cb81ae3 100644 --- a/src/app/utils/profileFields.ts +++ b/src/app/utils/profileFields.ts @@ -152,7 +152,7 @@ export async function loadColorPreference( } export function extractMemberColorPreference(room: Room | undefined, userId: string): ColorPreference | undefined { - if (!room) return undefined; + if (!room || typeof (room as Room).getMember !== 'function' || !userId) return undefined; const member = room.getMember(userId); const content = member?.events.member?.getContent(); if (!content) return undefined; diff --git a/vite.config.js b/vite.config.js index c6bcd87..e70c74f 100644 --- a/vite.config.js +++ b/vite.config.js @@ -56,7 +56,8 @@ const copyFiles = { { src: 'public/update/**/*', dest: 'update', - rename: (_name, _ext, fullPath) => fullPath.replace(/^public[/\\]update[/\\]/, ''), + // stripBase removes public/update from the matched path; rename alone only changes the filename. + rename: { stripBase: 2 }, }, ], };