diff --git a/src/app/components/create-room/AdditionalCreatorInput.tsx b/src/app/components/create-room/AdditionalCreatorInput.tsx index 84485b5b..51334b49 100644 --- a/src/app/components/create-room/AdditionalCreatorInput.tsx +++ b/src/app/components/create-room/AdditionalCreatorInput.tsx @@ -34,9 +34,11 @@ import { findAndReplace } from '../../utils/findAndReplace'; import { highlightText } from '../../styles/CustomHtml.css'; import { makeHighlightRegex } from '../../plugins/react-custom-html-parser'; -export const useAdditionalCreators = () => { +export const useAdditionalCreators = (defaultCreators?: string[]) => { const mx = useMatrixClient(); - const [additionalCreators, setAdditionalCreators] = useState([]); + const [additionalCreators, setAdditionalCreators] = useState( + () => defaultCreators?.filter((id) => id !== mx.getSafeUserId()) ?? [] + ); const addAdditionalCreator = (userId: string) => { if (userId === mx.getSafeUserId()) return; @@ -75,11 +77,13 @@ type AdditionalCreatorInputProps = { additionalCreators: string[]; onSelect: (userId: string) => void; onRemove: (userId: string) => void; + disabled?: boolean; }; export function AdditionalCreatorInput({ additionalCreators, onSelect, onRemove, + disabled, }: AdditionalCreatorInputProps) { const mx = useMatrixClient(); const [menuCords, setMenuCords] = useState(); @@ -164,6 +168,7 @@ export function AdditionalCreatorInput({ radii="Pill" after={} onClick={() => onRemove(creator)} + disabled={disabled} > {creator} @@ -289,6 +294,7 @@ export function AdditionalCreatorInput({ radii="Pill" onClick={handleOpenMenu} aria-pressed={!!menuCords} + disabled={disabled} > diff --git a/src/app/features/common-settings/general/RoomUpgrade.tsx b/src/app/features/common-settings/general/RoomUpgrade.tsx index 14db77f1..3fc28c5c 100644 --- a/src/app/features/common-settings/general/RoomUpgrade.tsx +++ b/src/app/features/common-settings/general/RoomUpgrade.tsx @@ -1,4 +1,4 @@ -import React, { FormEventHandler, useCallback, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { Button, color, @@ -14,10 +14,9 @@ import { IconButton, Icon, Icons, - Input, } from 'folds'; import FocusTrap from 'focus-trap-react'; -import { MatrixError } from 'matrix-js-sdk'; +import { MatrixError, Method } from 'matrix-js-sdk'; import { RoomTombstoneEventContent } from 'matrix-js-sdk/lib/types'; import { SequenceCard } from '../../../components/sequence-card'; import { SequenceCardStyle } from '../../room-settings/styles.css'; @@ -31,6 +30,133 @@ import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; import { useCapabilities } from '../../../hooks/useCapabilities'; import { stopPropagation } from '../../../utils/keyboard'; import { RoomPermissionsAPI } from '../../../hooks/useRoomPermissions'; +import { + AdditionalCreatorInput, + RoomVersionSelector, + useAdditionalCreators, +} from '../../../components/create-room'; +import { useAlive } from '../../../hooks/useAlive'; +import { creatorsSupported } from '../../../utils/matrix'; +import { useRoomCreators } from '../../../hooks/useRoomCreators'; +import { BreakWord } from '../../../styles/Text.css'; + +function RoomUpgradeDialog({ requestClose }: { requestClose: () => void }) { + const mx = useMatrixClient(); + const room = useRoom(); + const alive = useAlive(); + const creators = useRoomCreators(room); + + const capabilities = useCapabilities(); + const roomVersions = capabilities['m.room_versions']; + const [selectedRoomVersion, selectRoomVersion] = useState(roomVersions?.default ?? '1'); + useEffect(() => { + // capabilities load async + selectRoomVersion(roomVersions?.default ?? '1'); + }, [roomVersions?.default]); + + const allowAdditionalCreators = creatorsSupported(selectedRoomVersion); + const { additionalCreators, addAdditionalCreator, removeAdditionalCreator } = + useAdditionalCreators(Array.from(creators)); + + const [upgradeState, upgrade] = useAsyncCallback( + useCallback( + async (version: string, newAdditionalCreators?: string[]) => { + await mx.http.authedRequest(Method.Post, `/rooms/${room.roomId}/upgrade`, undefined, { + new_version: version, + additional_creators: newAdditionalCreators, + }); + }, + [mx, room] + ) + ); + + const upgrading = upgradeState.status === AsyncStatus.Loading; + + const handleUpgradeRoom = () => { + const version = selectedRoomVersion; + + upgrade(version, allowAdditionalCreators ? additionalCreators : undefined).then(() => { + if (alive()) { + requestClose(); + } + }); + }; + + return ( + }> + + + +
+ + {room.isSpaceRoom() ? 'Space Upgrade' : 'Room Upgrade'} + + + + +
+ + + This action is irreversible! + + + Options + + {allowAdditionalCreators && ( + + + + )} + + {upgradeState.status === AsyncStatus.Error && ( + + {(upgradeState.error as MatrixError).message} + + )} + + +
+
+
+
+ ); +} type RoomUpgradeProps = { permissions: RoomPermissionsAPI; @@ -47,9 +173,6 @@ export function RoomUpgrade({ permissions, requestClose }: RoomUpgradeProps) { const roomVersion = createContent?.room_version ?? '1'; const predecessorRoomId = createContent?.predecessor?.room_id; - const capabilities = useCapabilities(); - const defaultRoomVersion = capabilities['m.room_versions']?.default; - const tombstoneContent = useStateEvent( room, StateEvent.RoomTombstone @@ -80,31 +203,8 @@ export function RoomUpgrade({ permissions, requestClose }: RoomUpgradeProps) { } }; - const [upgradeState, upgrade] = useAsyncCallback( - useCallback( - async (version: string) => { - await mx.upgradeRoom(room.roomId, version); - }, - [mx, room] - ) - ); - - const upgrading = upgradeState.status === AsyncStatus.Loading; - const [prompt, setPrompt] = useState(false); - const handleSubmitUpgrade: FormEventHandler = (evt) => { - evt.preventDefault(); - - const target = evt.target as HTMLFormElement | undefined; - const versionInput = target?.versionInput as HTMLInputElement | undefined; - const version = versionInput?.value.trim(); - if (!version) return; - - upgrade(version); - setPrompt(false); - }; - return ( } + disabled={!canUpgrade} onClick={() => setPrompt(true)} > Upgrade @@ -160,63 +259,7 @@ export function RoomUpgrade({ permissions, requestClose }: RoomUpgradeProps) { } > - {upgradeState.status === AsyncStatus.Error && ( - - {(upgradeState.error as MatrixError).message} - - )} - - {prompt && ( - }> - - setPrompt(false), - clickOutsideDeactivates: true, - escapeDeactivates: stopPropagation, - }} - > - -
- - {room.isSpaceRoom() ? 'Space Upgrade' : 'Room Upgrade'} - - setPrompt(false)} radii="300"> - - -
- - - This action is irreversible! - - - Version - - - - -
-
-
-
- )} + {prompt && setPrompt(false)} />}
);