import { RoomHistoryVisibility } from './RoomHistoryVisibility';
import { RoomJoinRules } from './RoomJoinRules';
import { RoomLocalAddresses, RoomPublishedAddresses } from './RoomAddress';
+import { RoomPublish } from './RoomPublish';
import { RoomUpgrade } from './RoomUpgrade';
type GeneralProps = {
<RoomJoinRules powerLevels={powerLevels} />
<RoomHistoryVisibility powerLevels={powerLevels} />
<RoomEncryption powerLevels={powerLevels} />
+ <RoomPublish powerLevels={powerLevels} />
</Box>
<Box direction="Column" gap="100">
<Text size="L400">Addresses</Text>
--- /dev/null
+import React from 'react';
+import { Box, color, Spinner, Switch, Text } from 'folds';
+import { MatrixError } from 'matrix-js-sdk';
+import { SequenceCard } from '../../../components/sequence-card';
+import { SequenceCardStyle } from '../styles.css';
+import { SettingTile } from '../../../components/setting-tile';
+import { useRoom } from '../../../hooks/useRoom';
+import { useRoomDirectoryVisibility } from '../../../hooks/useRoomDirectoryVisibility';
+import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
+import { IPowerLevels, powerLevelAPI } from '../../../hooks/usePowerLevels';
+import { StateEvent } from '../../../../types/matrix/room';
+import { useMatrixClient } from '../../../hooks/useMatrixClient';
+
+type RoomPublishProps = {
+ powerLevels: IPowerLevels;
+};
+export function RoomPublish({ powerLevels }: RoomPublishProps) {
+ const mx = useMatrixClient();
+ const room = useRoom();
+ const userPowerLevel = powerLevelAPI.getPowerLevel(powerLevels, mx.getSafeUserId());
+ const canEditCanonical = powerLevelAPI.canSendStateEvent(
+ powerLevels,
+ StateEvent.RoomCanonicalAlias,
+ userPowerLevel
+ );
+
+ const { visibilityState, setVisibility } = useRoomDirectoryVisibility(room.roomId);
+
+ const [toggleState, toggleVisibility] = useAsyncCallback(setVisibility);
+
+ const loading =
+ visibilityState.status === AsyncStatus.Loading || toggleState.status === AsyncStatus.Loading;
+
+ return (
+ <SequenceCard
+ className={SequenceCardStyle}
+ variant="SurfaceVariant"
+ direction="Column"
+ gap="400"
+ >
+ <SettingTile
+ title="Publish To Directory"
+ after={
+ <Box gap="200" alignItems="Center">
+ {loading && <Spinner variant="Secondary" />}
+ {!loading && visibilityState.status === AsyncStatus.Success && (
+ <Switch
+ value={visibilityState.data}
+ onChange={toggleVisibility}
+ disabled={!canEditCanonical}
+ />
+ )}
+ </Box>
+ }
+ >
+ {visibilityState.status === AsyncStatus.Error && (
+ <Text style={{ color: color.Critical.Main }} size="T200">
+ {(visibilityState.error as MatrixError).message}
+ </Text>
+ )}
+
+ {toggleState.status === AsyncStatus.Error && (
+ <Text style={{ color: color.Critical.Main }} size="T200">
+ {(toggleState.error as MatrixError).message}
+ </Text>
+ )}
+ </SettingTile>
+ </SequenceCard>
+ );
+}
--- /dev/null
+import { useCallback, useEffect } from 'react';
+import { Visibility } from 'matrix-js-sdk';
+import { useAsyncCallback } from './useAsyncCallback';
+import { useMatrixClient } from './useMatrixClient';
+
+export const useRoomDirectoryVisibility = (roomId: string) => {
+ const mx = useMatrixClient();
+
+ const [visibilityState, loadVisibility] = useAsyncCallback(
+ useCallback(async () => {
+ const v = await mx.getRoomDirectoryVisibility(roomId);
+ return v.visibility === Visibility.Public;
+ }, [mx, roomId])
+ );
+
+ useEffect(() => {
+ loadVisibility();
+ }, [loadVisibility]);
+
+ const setVisibility = useCallback(
+ async (visibility: boolean) => {
+ await mx.setRoomDirectoryVisibility(
+ roomId,
+ visibility ? Visibility.Public : Visibility.Private
+ );
+ await loadVisibility();
+ },
+ [mx, roomId, loadVisibility]
+ );
+
+ return {
+ visibilityState,
+ setVisibility,
+ };
+};