import React, { useEffect, useState } from 'react'; import { Box, Text, IconButton, Icon, Icons, Scroll, Button, Spinner, config, toRem } from 'folds'; import { Page, PageContent, PageHeader } from '../../../components/page'; import { SequenceCard } from '../../../components/sequence-card'; import { SequenceCardStyle } from '../styles.css'; import { SettingTile } from '../../../components/setting-tile'; import pkg from '../../../../../package.json'; import { clearCacheAndReload } from '../../../../client/initMatrix'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { getOriginBaseUrl, withOriginBaseUrl } from '../../../pages/pathUtils'; const LotusLogo = withOriginBaseUrl(getOriginBaseUrl(), '/Lotus.png'); type MSC1929Contact = { matrix_id?: string; email_address?: string; role?: string; }; type MSC1929Support = { contacts?: MSC1929Contact[]; support_page?: string; }; function isMSC1929Support(data: unknown): data is MSC1929Support { if (typeof data !== 'object' || data === null) return false; const d = data as Record; if ('contacts' in d && !Array.isArray(d.contacts)) return false; if ('support_page' in d && typeof d.support_page !== 'string') return false; return true; } function formatRole(role?: string): string { if (!role) return 'Contact'; if (role === 'm.role.admin') return 'Admin'; if (role === 'm.role.security') return 'Security'; return role.startsWith('m.role.') ? role.slice(7) : role; } function useServerSupport(): { support: MSC1929Support | null; loading: boolean } { const mx = useMatrixClient(); const [support, setSupport] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const controller = new AbortController(); // MSC1929 support info is served from the MXID server-name host (like // /.well-known/matrix/client), which on delegated/split-domain servers is // NOT the client-API URL. Derive it from the user's domain. const serverName = mx.getDomain(); if (!serverName) { setLoading(false); return undefined; } setLoading(true); fetch(`https://${serverName}/.well-known/matrix/support`, { signal: controller.signal }) .then((res) => { if (!res.ok) return null; return res.json(); }) .then((data) => { if (isMSC1929Support(data) && (data.contacts?.length || data.support_page)) { setSupport(data); } }) .catch((e) => { if (e.name !== 'AbortError') { // Graceful degradation — server may not have this configured } }) .finally(() => setLoading(false)); return () => controller.abort(); }, [mx]); return { support, loading }; } type AboutProps = { requestClose: () => void; }; export function About({ requestClose }: AboutProps) { const mx = useMatrixClient(); const { support: serverSupport, loading: supportLoading } = useServerSupport(); return ( About Lotus Chat logo Lotus Chat v{pkg.version} A Matrix client for Lotus Guild. Options clearCacheAndReload(mx)} variant="Secondary" fill="Soft" size="300" radii="300" outlined > Clear Cache } /> {(serverSupport || supportLoading) && ( Homeserver Support {supportLoading && !serverSupport && ( Loading support info… )} {serverSupport?.contacts && serverSupport.contacts.length > 0 && ( {serverSupport.contacts.map((contact, i) => ( {formatRole(contact.role)}: {contact.matrix_id && ( {contact.matrix_id} )} {contact.email_address && ( {contact.email_address} )} ))} )} {serverSupport?.support_page && ( Support Page: {serverSupport.support_page} )} )} Credits
  • The Lotus Chat logo is a derivative work based on the original{' '} Cinny {' '} logo by{' '} Ajay Bura {' '} and contributors, used under the terms of{' '} CC-BY 4.0 . The modified logo is © Lotus Guild, also under CC-BY 4.0.
  • Lotus Chat is a fork of{' '} Cinny {' '} by Ajay Bura and contributors, used under the terms of{' '} AGPL-3.0 .
  • The{' '} matrix-js-sdk {' '} is ©{' '} The Matrix.org Foundation C.I.C {' '} used under the terms of{' '} Apache 2.0 .
  • The{' '} twemoji-colr {' '} font is ©{' '} Mozilla Foundation {' '} used under the terms of{' '} Apache 2.0 .
  • The{' '} Twemoji {' '} emoji art is ©{' '} Twitter, Inc and other contributors {' '} used under the terms of{' '} CC-BY 4.0 .
  • The{' '} Material sound resources {' '} are ©{' '} Google {' '} used under the terms of{' '} CC-BY 4.0 .
  • ); }