Fix Android updates dialog, mobile About page, and user color crash guard.
All checks were successful
Trigger cinny-mobile / dispatch (push) Successful in 2s
All checks were successful
Trigger cinny-mobile / dispatch (push) Successful in 2s
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.
This commit is contained in:
@@ -96,6 +96,12 @@
|
|||||||
</script>
|
</script>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<div id="portalContainer"></div>
|
<div id="portalContainer"></div>
|
||||||
|
<style>
|
||||||
|
#portalContainer {
|
||||||
|
position: relative;
|
||||||
|
z-index: 10000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<script type="module" src="./src/index.tsx"></script>
|
<script type="module" src="./src/index.tsx"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import React, { ReactNode, useCallback, useState } from 'react';
|
import React, { ReactNode, useCallback, useState } from 'react';
|
||||||
import FocusTrap from 'focus-trap-react';
|
import FocusTrap from 'focus-trap-react';
|
||||||
|
import { useAtomValue } from 'jotai';
|
||||||
import { Modal, Overlay, OverlayBackdrop, OverlayCenter, PopOutContainerProvider } from 'folds';
|
import { Modal, Overlay, OverlayBackdrop, OverlayCenter, PopOutContainerProvider } from 'folds';
|
||||||
import { stopPropagation } from '../utils/keyboard';
|
import { stopPropagation } from '../utils/keyboard';
|
||||||
|
import { releaseNotesDialogAtom } from '../state/releaseNotes';
|
||||||
|
|
||||||
type Modal500Props = {
|
type Modal500Props = {
|
||||||
requestClose: () => void;
|
requestClose: () => void;
|
||||||
@@ -10,11 +12,13 @@ type Modal500Props = {
|
|||||||
export function Modal500({ requestClose, children }: Modal500Props) {
|
export function Modal500({ requestClose, children }: Modal500Props) {
|
||||||
const [modalEl, setModalEl] = useState<HTMLDivElement | null>(null);
|
const [modalEl, setModalEl] = useState<HTMLDivElement | null>(null);
|
||||||
const modalRef = useCallback((el: HTMLDivElement | null) => setModalEl(el), []);
|
const modalRef = useCallback((el: HTMLDivElement | null) => setModalEl(el), []);
|
||||||
|
const releaseNotesOpen = useAtomValue(releaseNotesDialogAtom).open;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Overlay open backdrop={<OverlayBackdrop />}>
|
<Overlay open backdrop={<OverlayBackdrop />}>
|
||||||
<OverlayCenter>
|
<OverlayCenter>
|
||||||
<FocusTrap
|
<FocusTrap
|
||||||
|
active={!releaseNotesOpen}
|
||||||
focusTrapOptions={{
|
focusTrapOptions={{
|
||||||
initialFocus: false,
|
initialFocus: false,
|
||||||
clickOutsideDeactivates: true,
|
clickOutsideDeactivates: true,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ type PageRootProps = {
|
|||||||
export function PageRoot({ nav, children }: PageRootProps) {
|
export function PageRoot({ nav, children }: PageRootProps) {
|
||||||
const screenSize = useScreenSizeContext();
|
const screenSize = useScreenSizeContext();
|
||||||
const showCompactMaster = useShowCompactMasterView();
|
const showCompactMaster = useShowCompactMasterView();
|
||||||
|
const showDetail = !showCompactMaster || nav == null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box grow="Yes" className={ContainerColor({ variant: 'Background' })}>
|
<Box grow="Yes" className={ContainerColor({ variant: 'Background' })}>
|
||||||
@@ -23,7 +24,7 @@ export function PageRoot({ nav, children }: PageRootProps) {
|
|||||||
{screenSize !== ScreenSize.Mobile && (
|
{screenSize !== ScreenSize.Mobile && (
|
||||||
<Line variant="Background" size="300" direction="Vertical" />
|
<Line variant="Background" size="300" direction="Vertical" />
|
||||||
)}
|
)}
|
||||||
{!showCompactMaster && children}
|
{showDetail && children}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
Scroll,
|
Scroll,
|
||||||
Spinner,
|
Spinner,
|
||||||
Text,
|
Text,
|
||||||
|
usePopOutContainer,
|
||||||
} from 'folds';
|
} from 'folds';
|
||||||
import { Icon, Icons } from '../icons';
|
import { Icon, Icons } from '../icons';
|
||||||
import { stopPropagation } from '../../utils/keyboard';
|
import { stopPropagation } from '../../utils/keyboard';
|
||||||
@@ -36,6 +37,7 @@ export function UpdatesDialog({
|
|||||||
onClose,
|
onClose,
|
||||||
}: UpdatesDialogProps) {
|
}: UpdatesDialogProps) {
|
||||||
const [showOlderList, setShowOlderList] = useState(false);
|
const [showOlderList, setShowOlderList] = useState(false);
|
||||||
|
const popOutContainer = usePopOutContainer();
|
||||||
|
|
||||||
const displayVersion = activeDoc?.version;
|
const displayVersion = activeDoc?.version;
|
||||||
const displayTitle = activeDoc?.title ?? (displayVersion ? `Version ${displayVersion}` : 'Release notes');
|
const displayTitle = activeDoc?.title ?? (displayVersion ? `Version ${displayVersion}` : 'Release notes');
|
||||||
@@ -48,7 +50,9 @@ export function UpdatesDialog({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const portalTarget =
|
const portalTarget =
|
||||||
document.getElementById('portalContainer') ?? document.body;
|
popOutContainer ??
|
||||||
|
document.getElementById('portalContainer') ??
|
||||||
|
document.body;
|
||||||
|
|
||||||
return createPortal(
|
return createPortal(
|
||||||
<div className={css.PortalLayer}>
|
<div className={css.PortalLayer}>
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ export function About({ requestClose }: AboutProps) {
|
|||||||
const [version, setVersion] = useState<string>('');
|
const [version, setVersion] = useState<string>('');
|
||||||
const [protocolStatus, setProtocolStatus] = useState<string>('Checking desktop protocol integration...');
|
const [protocolStatus, setProtocolStatus] = useState<string>('Checking desktop protocol integration...');
|
||||||
const [protocolBusy, setProtocolBusy] = useState<boolean>(false);
|
const [protocolBusy, setProtocolBusy] = useState<boolean>(false);
|
||||||
|
const [updatePreview, setUpdatePreview] = useState<{ title: string; description: string } | null>(
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const formatProtocolStatus = useCallback((data: {
|
const formatProtocolStatus = useCallback((data: {
|
||||||
scheme: string;
|
scheme: string;
|
||||||
@@ -101,8 +104,6 @@ export function About({ requestClose }: AboutProps) {
|
|||||||
getCurrentUpdatePreview().then(setUpdatePreview).catch(() => setUpdatePreview(null));
|
getCurrentUpdatePreview().then(setUpdatePreview).catch(() => setUpdatePreview(null));
|
||||||
}, [refreshProtocolStatus]);
|
}, [refreshProtocolStatus]);
|
||||||
|
|
||||||
const [updatePreview, setUpdatePreview] = useState<{ title: string; description: string } | null>(null);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
<PageHeader outlined={false}>
|
<PageHeader outlined={false}>
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ export async function loadColorPreference(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function extractMemberColorPreference(room: Room | undefined, userId: string): ColorPreference | undefined {
|
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 member = room.getMember(userId);
|
||||||
const content = member?.events.member?.getContent();
|
const content = member?.events.member?.getContent();
|
||||||
if (!content) return undefined;
|
if (!content) return undefined;
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ const copyFiles = {
|
|||||||
{
|
{
|
||||||
src: 'public/update/**/*',
|
src: 'public/update/**/*',
|
||||||
dest: '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 },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user