Support room version 12 (#2399)
* WIP - support room version 12 * add room creators hook * revert changes from powerlevels * improve use room creators hook * add hook to get dm users * add options to add creators in create room/space * add member item component in member drawer * remove unused import * extract member drawer header component * get room creators as set only if room version support them * add room permissions hook * support room v12 creators power * make predecessor event id optional * add info about founders in permissions * allow to create infinite powers to room creators * allow everyone with permission to create infinite power * handle additional creators in room upgrade * add option to follow space tombstone
This commit is contained in:
parent
a79164318c
commit
fa575fc09d
58 changed files with 1718 additions and 780 deletions
|
|
@ -27,10 +27,7 @@ import { SequenceCardStyle } from '../styles.css';
|
|||
import { SettingTile } from '../../../components/setting-tile';
|
||||
import {
|
||||
getPowers,
|
||||
getTagIconSrc,
|
||||
getUsedPowers,
|
||||
PowerLevelTag,
|
||||
PowerLevelTagIcon,
|
||||
PowerLevelTags,
|
||||
usePowerLevelTags,
|
||||
} from '../../../hooks/usePowerLevelTags';
|
||||
|
|
@ -47,15 +44,17 @@ import { useFilePicker } from '../../../hooks/useFilePicker';
|
|||
import { CompactUploadCardRenderer } from '../../../components/upload-card';
|
||||
import { createUploadAtom, UploadSuccess } from '../../../state/upload';
|
||||
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
|
||||
import { StateEvent } from '../../../../types/matrix/room';
|
||||
import { MemberPowerTag, MemberPowerTagIcon, StateEvent } from '../../../../types/matrix/room';
|
||||
import { useAlive } from '../../../hooks/useAlive';
|
||||
import { BetaNoticeBadge } from '../../../components/BetaNoticeBadge';
|
||||
import { getPowerTagIconSrc } from '../../../hooks/useMemberPowerTag';
|
||||
import { creatorsSupported } from '../../../utils/matrix';
|
||||
|
||||
type EditPowerProps = {
|
||||
maxPower: number;
|
||||
power?: number;
|
||||
tag?: PowerLevelTag;
|
||||
onSave: (power: number, tag: PowerLevelTag) => void;
|
||||
tag?: MemberPowerTag;
|
||||
onSave: (power: number, tag: MemberPowerTag) => void;
|
||||
onClose: () => void;
|
||||
};
|
||||
function EditPower({ maxPower, power, tag, onSave, onClose }: EditPowerProps) {
|
||||
|
|
@ -63,6 +62,7 @@ function EditPower({ maxPower, power, tag, onSave, onClose }: EditPowerProps) {
|
|||
const room = useRoom();
|
||||
const roomToParents = useAtomValue(roomToParentsAtom);
|
||||
const useAuthentication = useMediaAuthentication();
|
||||
const supportCreators = creatorsSupported(room.getVersion());
|
||||
|
||||
const imagePackRooms = useImagePackRooms(room.roomId, roomToParents);
|
||||
|
||||
|
|
@ -70,9 +70,9 @@ function EditPower({ maxPower, power, tag, onSave, onClose }: EditPowerProps) {
|
|||
const pickFile = useFilePicker(setIconFile, false);
|
||||
|
||||
const [tagColor, setTagColor] = useState<string | undefined>(tag?.color);
|
||||
const [tagIcon, setTagIcon] = useState<PowerLevelTagIcon | undefined>(tag?.icon);
|
||||
const [tagIcon, setTagIcon] = useState<MemberPowerTagIcon | undefined>(tag?.icon);
|
||||
const uploadingIcon = iconFile && !tagIcon;
|
||||
const tagIconSrc = tagIcon && getTagIconSrc(mx, useAuthentication, tagIcon);
|
||||
const tagIconSrc = tagIcon && getPowerTagIconSrc(mx, useAuthentication, tagIcon);
|
||||
|
||||
const iconUploadAtom = useMemo(() => {
|
||||
if (iconFile) return createUploadAtom(iconFile);
|
||||
|
|
@ -101,11 +101,11 @@ function EditPower({ maxPower, power, tag, onSave, onClose }: EditPowerProps) {
|
|||
|
||||
const tagPower = parseInt(powerInput.value, 10);
|
||||
if (Number.isNaN(tagPower)) return;
|
||||
if (tagPower > maxPower) return;
|
||||
|
||||
const tagName = nameInput.value.trim();
|
||||
if (!tagName) return;
|
||||
|
||||
const editedTag: PowerLevelTag = {
|
||||
const editedTag: MemberPowerTag = {
|
||||
name: tagName,
|
||||
color: tagColor,
|
||||
icon: tagIcon,
|
||||
|
|
@ -165,7 +165,7 @@ function EditPower({ maxPower, power, tag, onSave, onClose }: EditPowerProps) {
|
|||
radii="300"
|
||||
type="number"
|
||||
placeholder="75"
|
||||
max={maxPower}
|
||||
max={supportCreators ? undefined : maxPower}
|
||||
outlined={typeof power === 'number'}
|
||||
readOnly={typeof power === 'number'}
|
||||
required
|
||||
|
|
@ -298,7 +298,7 @@ export function PowersEditor({ powerLevels, requestClose }: PowersEditorProps) {
|
|||
return [up, Math.max(...Array.from(up))];
|
||||
}, [powerLevels]);
|
||||
|
||||
const [powerLevelTags] = usePowerLevelTags(room, powerLevels);
|
||||
const powerLevelTags = usePowerLevelTags(room, powerLevels);
|
||||
const [editedPowerTags, setEditedPowerTags] = useState<PowerLevelTags>();
|
||||
const [deleted, setDeleted] = useState<Set<number>>(new Set());
|
||||
|
||||
|
|
@ -317,7 +317,7 @@ export function PowersEditor({ powerLevels, requestClose }: PowersEditorProps) {
|
|||
}, []);
|
||||
|
||||
const handleSaveTag = useCallback(
|
||||
(power: number, tag: PowerLevelTag) => {
|
||||
(power: number, tag: MemberPowerTag) => {
|
||||
setEditedPowerTags((tags) => {
|
||||
const editedTags = { ...(tags ?? powerLevelTags) };
|
||||
editedTags[power] = tag;
|
||||
|
|
@ -419,7 +419,8 @@ export function PowersEditor({ powerLevels, requestClose }: PowersEditorProps) {
|
|||
</SequenceCard>
|
||||
{getPowers(powerTags).map((power) => {
|
||||
const tag = powerTags[power];
|
||||
const tagIconSrc = tag.icon && getTagIconSrc(mx, useAuthentication, tag.icon);
|
||||
const tagIconSrc =
|
||||
tag.icon && getPowerTagIconSrc(mx, useAuthentication, tag.icon);
|
||||
|
||||
return (
|
||||
<SequenceCard
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue