Move space room discovery & management into the space room view
This commit is contained in:
parent
09601f1071
commit
8c6d92cc99
7 changed files with 100 additions and 123 deletions
|
@ -330,10 +330,6 @@ $activeBorderColor: $secondary-fg-color;
|
||||||
mask-image: url('$(res)/img/element-icons/leave.svg');
|
mask-image: url('$(res)/img/element-icons/leave.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpacePanel_iconHome::before {
|
|
||||||
mask-image: url('$(res)/img/element-icons/roomlist/home.svg');
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SpacePanel_iconMembers::before {
|
.mx_SpacePanel_iconMembers::before {
|
||||||
mask-image: url('$(res)/img/element-icons/room/members.svg');
|
mask-image: url('$(res)/img/element-icons/room/members.svg');
|
||||||
}
|
}
|
||||||
|
|
|
@ -365,12 +365,13 @@ $SpaceRoomViewInnerWidth: 428px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_list {
|
.mx_SearchBox {
|
||||||
max-width: 600px;
|
margin-left: 4px;
|
||||||
|
max-width: 670px;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_roomTile_actions {
|
.mx_SpaceRoomDirectory_list {
|
||||||
display: none;
|
max-width: 700px;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,10 +80,10 @@ import DialPadModal from "../views/voip/DialPadModal";
|
||||||
import { showToast as showMobileGuideToast } from '../../toasts/MobileGuideToast';
|
import { showToast as showMobileGuideToast } from '../../toasts/MobileGuideToast';
|
||||||
import { shouldUseLoginForWelcome } from "../../utils/pages";
|
import { shouldUseLoginForWelcome } from "../../utils/pages";
|
||||||
import SpaceStore from "../../stores/SpaceStore";
|
import SpaceStore from "../../stores/SpaceStore";
|
||||||
import SpaceRoomDirectory from "./SpaceRoomDirectory";
|
|
||||||
import {replaceableComponent} from "../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../utils/replaceableComponent";
|
||||||
import RoomListStore from "../../stores/room-list/RoomListStore";
|
import RoomListStore from "../../stores/room-list/RoomListStore";
|
||||||
import {RoomUpdateCause} from "../../stores/room-list/models";
|
import {RoomUpdateCause} from "../../stores/room-list/models";
|
||||||
|
import defaultDispatcher from "../../dispatcher/dispatcher";
|
||||||
|
|
||||||
/** constants for MatrixChat.state.view */
|
/** constants for MatrixChat.state.view */
|
||||||
export enum Views {
|
export enum Views {
|
||||||
|
@ -690,10 +690,10 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
case Action.ViewRoomDirectory: {
|
case Action.ViewRoomDirectory: {
|
||||||
if (SpaceStore.instance.activeSpace) {
|
if (SpaceStore.instance.activeSpace) {
|
||||||
Modal.createTrackedDialog("Space room directory", "", SpaceRoomDirectory, {
|
defaultDispatcher.dispatch({
|
||||||
space: SpaceStore.instance.activeSpace,
|
action: "view_room",
|
||||||
initialText: payload.initialText,
|
room_id: SpaceStore.instance.activeSpace.roomId,
|
||||||
}, "mx_SpaceRoomDirectory_dialogWrapper", false, true);
|
});
|
||||||
} else {
|
} else {
|
||||||
const RoomDirectory = sdk.getComponent("structures.RoomDirectory");
|
const RoomDirectory = sdk.getComponent("structures.RoomDirectory");
|
||||||
Modal.createTrackedDialog('Room directory', '', RoomDirectory, {
|
Modal.createTrackedDialog('Room directory', '', RoomDirectory, {
|
||||||
|
|
|
@ -40,10 +40,11 @@ import InfoTooltip from "../views/elements/InfoTooltip";
|
||||||
import TextWithTooltip from "../views/elements/TextWithTooltip";
|
import TextWithTooltip from "../views/elements/TextWithTooltip";
|
||||||
import {useStateToggle} from "../../hooks/useStateToggle";
|
import {useStateToggle} from "../../hooks/useStateToggle";
|
||||||
|
|
||||||
interface IProps {
|
interface IHierarchyProps {
|
||||||
space: Room;
|
space: Room;
|
||||||
initialText?: string;
|
initialText?: string;
|
||||||
onFinished(): void;
|
refreshToken?: any;
|
||||||
|
showRoom(room: ISpaceSummaryRoom, viaServers?: string[], autoJoin?: boolean): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
|
@ -344,22 +345,20 @@ export const useSpaceSummary = (cli: MatrixClient, space: Room, refreshToken?: a
|
||||||
}, [space, refreshToken], []);
|
}, [space, refreshToken], []);
|
||||||
};
|
};
|
||||||
|
|
||||||
const SpaceRoomDirectory: React.FC<IProps> = ({ space, initialText = "", onFinished }) => {
|
export const SpaceHierarchy: React.FC<IHierarchyProps> = ({
|
||||||
|
space,
|
||||||
|
initialText = "",
|
||||||
|
showRoom,
|
||||||
|
refreshToken,
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const userId = cli.getUserId();
|
const userId = cli.getUserId();
|
||||||
const [query, setQuery] = useState(initialText);
|
const [query, setQuery] = useState(initialText);
|
||||||
|
|
||||||
const onCreateRoomClick = () => {
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'view_create_room',
|
|
||||||
public: true,
|
|
||||||
});
|
|
||||||
onFinished();
|
|
||||||
};
|
|
||||||
|
|
||||||
const [selected, setSelected] = useState(new Map<string, Set<string>>()); // Map<parentId, Set<childId>>
|
const [selected, setSelected] = useState(new Map<string, Set<string>>()); // Map<parentId, Set<childId>>
|
||||||
|
|
||||||
const [rooms, parentChildMap, viaMap, childParentMap] = useSpaceSummary(cli, space);
|
const [rooms, parentChildMap, viaMap, childParentMap] = useSpaceSummary(cli, space, refreshToken);
|
||||||
|
|
||||||
const roomsMap = useMemo(() => {
|
const roomsMap = useMemo(() => {
|
||||||
if (!rooms) return null;
|
if (!rooms) return null;
|
||||||
|
@ -394,21 +393,6 @@ const SpaceRoomDirectory: React.FC<IProps> = ({ space, initialText = "", onFinis
|
||||||
return roomsMap;
|
return roomsMap;
|
||||||
}, [rooms, childParentMap, query]);
|
}, [rooms, childParentMap, query]);
|
||||||
|
|
||||||
const title = <React.Fragment>
|
|
||||||
<RoomAvatar room={space} height={32} width={32} />
|
|
||||||
<div>
|
|
||||||
<h1>{ _t("Explore rooms") }</h1>
|
|
||||||
<div><RoomName room={space} /></div>
|
|
||||||
</div>
|
|
||||||
</React.Fragment>;
|
|
||||||
|
|
||||||
const explanation =
|
|
||||||
_t("If you can't find the room you're looking for, ask for an invite or <a>create a new room</a>.", null,
|
|
||||||
{a: sub => {
|
|
||||||
return <AccessibleButton kind="link" onClick={onCreateRoomClick}>{sub}</AccessibleButton>;
|
|
||||||
}},
|
|
||||||
);
|
|
||||||
|
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const [removing, setRemoving] = useState(false);
|
const [removing, setRemoving] = useState(false);
|
||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
|
@ -528,10 +512,9 @@ const SpaceRoomDirectory: React.FC<IProps> = ({ space, initialText = "", onFinis
|
||||||
}}
|
}}
|
||||||
onViewRoomClick={(roomId, autoJoin) => {
|
onViewRoomClick={(roomId, autoJoin) => {
|
||||||
showRoom(roomsMap.get(roomId), Array.from(viaMap.get(roomId) || []), autoJoin);
|
showRoom(roomsMap.get(roomId), Array.from(viaMap.get(roomId) || []), autoJoin);
|
||||||
onFinished();
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<hr />
|
{ children && <hr /> }
|
||||||
</>;
|
</>;
|
||||||
} else {
|
} else {
|
||||||
results = <div className="mx_SpaceRoomDirectory_noResults">
|
results = <div className="mx_SpaceRoomDirectory_noResults">
|
||||||
|
@ -550,34 +533,78 @@ const SpaceRoomDirectory: React.FC<IProps> = ({ space, initialText = "", onFinis
|
||||||
</div> }
|
</div> }
|
||||||
<AutoHideScrollbar className="mx_SpaceRoomDirectory_list">
|
<AutoHideScrollbar className="mx_SpaceRoomDirectory_list">
|
||||||
{ results }
|
{ results }
|
||||||
<AccessibleButton
|
{ children }
|
||||||
onClick={onCreateRoomClick}
|
|
||||||
kind="primary"
|
|
||||||
className="mx_SpaceRoomDirectory_createRoom"
|
|
||||||
>
|
|
||||||
{ _t("Create room") }
|
|
||||||
</AccessibleButton>
|
|
||||||
</AutoHideScrollbar>
|
</AutoHideScrollbar>
|
||||||
</>;
|
</>;
|
||||||
} else {
|
} else if (!rooms) {
|
||||||
content = <Spinner />;
|
content = <Spinner />;
|
||||||
|
} else {
|
||||||
|
content = <p>{_t("Your server does not support showing space hierarchies.")}</p>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO loading state/error state
|
// TODO loading state/error state
|
||||||
|
return <>
|
||||||
|
<SearchBox
|
||||||
|
className="mx_textinput_icon mx_textinput_search"
|
||||||
|
placeholder={ _t("Search names and description") }
|
||||||
|
onSearch={setQuery}
|
||||||
|
autoFocus={true}
|
||||||
|
initialValue={initialText}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{ content }
|
||||||
|
</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
space: Room;
|
||||||
|
initialText?: string;
|
||||||
|
onFinished(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SpaceRoomDirectory: React.FC<IProps> = ({ space, onFinished, initialText }) => {
|
||||||
|
const onCreateRoomClick = () => {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'view_create_room',
|
||||||
|
public: true,
|
||||||
|
});
|
||||||
|
onFinished();
|
||||||
|
};
|
||||||
|
|
||||||
|
const title = <React.Fragment>
|
||||||
|
<RoomAvatar room={space} height={32} width={32} />
|
||||||
|
<div>
|
||||||
|
<h1>{ _t("Explore rooms") }</h1>
|
||||||
|
<div><RoomName room={space} /></div>
|
||||||
|
</div>
|
||||||
|
</React.Fragment>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseDialog className="mx_SpaceRoomDirectory" hasCancel={true} onFinished={onFinished} title={title}>
|
<BaseDialog className="mx_SpaceRoomDirectory" hasCancel={true} onFinished={onFinished} title={title}>
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content">
|
||||||
{ explanation }
|
{ _t("If you can't find the room you're looking for, ask for an invite or <a>create a new room</a>.",
|
||||||
|
null,
|
||||||
|
{a: sub => {
|
||||||
|
return <AccessibleButton kind="link" onClick={onCreateRoomClick}>{sub}</AccessibleButton>;
|
||||||
|
}},
|
||||||
|
) }
|
||||||
|
|
||||||
<SearchBox
|
<SpaceHierarchy
|
||||||
className="mx_textinput_icon mx_textinput_search"
|
space={space}
|
||||||
placeholder={ _t("Search names and description") }
|
showRoom={(room: ISpaceSummaryRoom, viaServers?: string[], autoJoin = false) => {
|
||||||
onSearch={setQuery}
|
showRoom(room, viaServers, autoJoin);
|
||||||
autoFocus={true}
|
onFinished();
|
||||||
initialValue={initialText}
|
}}
|
||||||
/>
|
initialText={initialText}
|
||||||
|
>
|
||||||
{ content }
|
<AccessibleButton
|
||||||
|
onClick={onCreateRoomClick}
|
||||||
|
kind="primary"
|
||||||
|
className="mx_SpaceRoomDirectory_createRoom"
|
||||||
|
>
|
||||||
|
{ _t("Create room") }
|
||||||
|
</AccessibleButton>
|
||||||
|
</SpaceHierarchy>
|
||||||
</div>
|
</div>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
);
|
);
|
||||||
|
|
|
@ -14,8 +14,8 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {RefObject, useContext, useMemo, useRef, useState} from "react";
|
import React, {RefObject, useContext, useRef, useState} from "react";
|
||||||
import {EventType, RoomType} from "matrix-js-sdk/src/@types/event";
|
import {EventType} from "matrix-js-sdk/src/@types/event";
|
||||||
import {Room} from "matrix-js-sdk/src/models/room";
|
import {Room} from "matrix-js-sdk/src/models/room";
|
||||||
import {EventSubscription} from "fbemitter";
|
import {EventSubscription} from "fbemitter";
|
||||||
|
|
||||||
|
@ -46,8 +46,7 @@ import {SetRightPanelPhasePayload} from "../../dispatcher/payloads/SetRightPanel
|
||||||
import {useStateArray} from "../../hooks/useStateArray";
|
import {useStateArray} from "../../hooks/useStateArray";
|
||||||
import SpacePublicShare from "../views/spaces/SpacePublicShare";
|
import SpacePublicShare from "../views/spaces/SpacePublicShare";
|
||||||
import {showAddExistingRooms, showCreateNewRoom, shouldShowSpaceSettings, showSpaceSettings} from "../../utils/space";
|
import {showAddExistingRooms, showCreateNewRoom, shouldShowSpaceSettings, showSpaceSettings} from "../../utils/space";
|
||||||
import {HierarchyLevel, ISpaceSummaryRoom, showRoom, useSpaceSummary} from "./SpaceRoomDirectory";
|
import {showRoom, SpaceHierarchy} from "./SpaceRoomDirectory";
|
||||||
import AutoHideScrollbar from "./AutoHideScrollbar";
|
|
||||||
import MemberAvatar from "../views/avatars/MemberAvatar";
|
import MemberAvatar from "../views/avatars/MemberAvatar";
|
||||||
import {useStateToggle} from "../../hooks/useStateToggle";
|
import {useStateToggle} from "../../hooks/useStateToggle";
|
||||||
import SpaceStore from "../../stores/SpaceStore";
|
import SpaceStore from "../../stores/SpaceStore";
|
||||||
|
@ -260,37 +259,6 @@ const SpaceLanding = ({ space }) => {
|
||||||
</AccessibleButton>;
|
</AccessibleButton>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [rooms, relations, viaMap] = useSpaceSummary(cli, space, refreshToken);
|
|
||||||
const [roomsMap, numRooms] = useMemo(() => {
|
|
||||||
if (!rooms) return [];
|
|
||||||
const roomsMap = new Map<string, ISpaceSummaryRoom>(rooms.map(r => [r.room_id, r]));
|
|
||||||
const numRooms = rooms.filter(r => r.room_type !== RoomType.Space).length;
|
|
||||||
return [roomsMap, numRooms];
|
|
||||||
}, [rooms]);
|
|
||||||
|
|
||||||
let previewRooms;
|
|
||||||
if (roomsMap) {
|
|
||||||
previewRooms = <AutoHideScrollbar className="mx_SpaceRoomDirectory_list">
|
|
||||||
<div className="mx_SpaceRoomDirectory_roomCount">
|
|
||||||
<h3>{ myMembership === "join" ? _t("Rooms") : _t("Default Rooms")}</h3>
|
|
||||||
<span>{ numRooms }</span>
|
|
||||||
</div>
|
|
||||||
<HierarchyLevel
|
|
||||||
spaceId={space.roomId}
|
|
||||||
rooms={roomsMap}
|
|
||||||
relations={relations}
|
|
||||||
parents={new Set()}
|
|
||||||
onViewRoomClick={(roomId, autoJoin) => {
|
|
||||||
showRoom(roomsMap.get(roomId), Array.from(viaMap.get(roomId) || []), autoJoin);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</AutoHideScrollbar>;
|
|
||||||
} else if (!rooms) {
|
|
||||||
previewRooms = <InlineSpinner />;
|
|
||||||
} else {
|
|
||||||
previewRooms = <p>{_t("Your server does not support showing space hierarchies.")}</p>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div className="mx_SpaceRoomView_landing">
|
return <div className="mx_SpaceRoomView_landing">
|
||||||
<RoomAvatar room={space} height={80} width={80} viewAvatarOnClick={true} />
|
<RoomAvatar room={space} height={80} width={80} viewAvatarOnClick={true} />
|
||||||
<div className="mx_SpaceRoomView_landing_name">
|
<div className="mx_SpaceRoomView_landing_name">
|
||||||
|
@ -336,7 +304,7 @@ const SpaceLanding = ({ space }) => {
|
||||||
{ settingsButton }
|
{ settingsButton }
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ previewRooms }
|
<SpaceHierarchy space={space} showRoom={showRoom} refreshToken={refreshToken} />
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,6 @@ import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
||||||
import {showRoomInviteDialog} from "../../../RoomInvite";
|
import {showRoomInviteDialog} from "../../../RoomInvite";
|
||||||
import InfoDialog from "../dialogs/InfoDialog";
|
import InfoDialog from "../dialogs/InfoDialog";
|
||||||
import {EventType} from "matrix-js-sdk/src/@types/event";
|
import {EventType} from "matrix-js-sdk/src/@types/event";
|
||||||
import SpaceRoomDirectory from "../../structures/SpaceRoomDirectory";
|
|
||||||
|
|
||||||
interface IItemProps {
|
interface IItemProps {
|
||||||
space?: Room;
|
space?: Room;
|
||||||
|
@ -115,17 +114,6 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
||||||
this.setState({contextMenuPosition: null});
|
this.setState({contextMenuPosition: null});
|
||||||
};
|
};
|
||||||
|
|
||||||
private onHomeClick = (ev: ButtonEvent) => {
|
|
||||||
ev.preventDefault();
|
|
||||||
ev.stopPropagation();
|
|
||||||
|
|
||||||
defaultDispatcher.dispatch({
|
|
||||||
action: "view_room",
|
|
||||||
room_id: this.props.space.roomId,
|
|
||||||
});
|
|
||||||
this.setState({contextMenuPosition: null}); // also close the menu
|
|
||||||
};
|
|
||||||
|
|
||||||
private onInviteClick = (ev: ButtonEvent) => {
|
private onInviteClick = (ev: ButtonEvent) => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
|
@ -206,9 +194,10 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
|
|
||||||
Modal.createTrackedDialog("Space room directory", "Space panel", SpaceRoomDirectory, {
|
defaultDispatcher.dispatch({
|
||||||
space: this.props.space,
|
action: "view_room",
|
||||||
}, "mx_SpaceRoomDirectory_dialogWrapper", false, true);
|
room_id: this.props.space.roomId,
|
||||||
|
});
|
||||||
this.setState({contextMenuPosition: null}); // also close the menu
|
this.setState({contextMenuPosition: null}); // also close the menu
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -249,6 +238,8 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
||||||
</IconizedContextMenuOptionList>;
|
</IconizedContextMenuOptionList>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const canAddRooms = this.props.space.currentState.maySendStateEvent(EventType.SpaceChild, userId);
|
||||||
|
|
||||||
let newRoomSection;
|
let newRoomSection;
|
||||||
if (this.props.space.currentState.maySendStateEvent(EventType.SpaceChild, userId)) {
|
if (this.props.space.currentState.maySendStateEvent(EventType.SpaceChild, userId)) {
|
||||||
newRoomSection = <IconizedContextMenuOptionList first>
|
newRoomSection = <IconizedContextMenuOptionList first>
|
||||||
|
@ -276,11 +267,6 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
||||||
</div>
|
</div>
|
||||||
<IconizedContextMenuOptionList first>
|
<IconizedContextMenuOptionList first>
|
||||||
{ inviteOption }
|
{ inviteOption }
|
||||||
<IconizedContextMenuOption
|
|
||||||
iconClassName="mx_SpacePanel_iconHome"
|
|
||||||
label={_t("Space Home")}
|
|
||||||
onClick={this.onHomeClick}
|
|
||||||
/>
|
|
||||||
<IconizedContextMenuOption
|
<IconizedContextMenuOption
|
||||||
iconClassName="mx_SpacePanel_iconMembers"
|
iconClassName="mx_SpacePanel_iconMembers"
|
||||||
label={_t("Members")}
|
label={_t("Members")}
|
||||||
|
@ -289,7 +275,7 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
||||||
{ settingsOption }
|
{ settingsOption }
|
||||||
<IconizedContextMenuOption
|
<IconizedContextMenuOption
|
||||||
iconClassName="mx_SpacePanel_iconExplore"
|
iconClassName="mx_SpacePanel_iconExplore"
|
||||||
label={_t("Explore rooms")}
|
label={canAddRooms ? _t("Manage & explore rooms") : _t("Explore rooms")}
|
||||||
onClick={this.onExploreRoomsClick}
|
onClick={this.onExploreRoomsClick}
|
||||||
/>
|
/>
|
||||||
</IconizedContextMenuOptionList>
|
</IconizedContextMenuOptionList>
|
||||||
|
|
|
@ -1018,8 +1018,8 @@
|
||||||
"Leave space": "Leave space",
|
"Leave space": "Leave space",
|
||||||
"Create new room": "Create new room",
|
"Create new room": "Create new room",
|
||||||
"Add existing room": "Add existing room",
|
"Add existing room": "Add existing room",
|
||||||
"Space Home": "Space Home",
|
|
||||||
"Members": "Members",
|
"Members": "Members",
|
||||||
|
"Manage & explore rooms": "Manage & explore rooms",
|
||||||
"Explore rooms": "Explore rooms",
|
"Explore rooms": "Explore rooms",
|
||||||
"Space options": "Space options",
|
"Space options": "Space options",
|
||||||
"Remove": "Remove",
|
"Remove": "Remove",
|
||||||
|
@ -2618,7 +2618,6 @@
|
||||||
"%(count)s rooms|one": "%(count)s room",
|
"%(count)s rooms|one": "%(count)s room",
|
||||||
"This room is suggested as a good one to join": "This room is suggested as a good one to join",
|
"This room is suggested as a good one to join": "This room is suggested as a good one to join",
|
||||||
"Suggested": "Suggested",
|
"Suggested": "Suggested",
|
||||||
"If you can't find the room you're looking for, ask for an invite or <a>create a new room</a>.": "If you can't find the room you're looking for, ask for an invite or <a>create a new room</a>.",
|
|
||||||
"%(count)s rooms and %(numSpaces)s spaces|other": "%(count)s rooms and %(numSpaces)s spaces",
|
"%(count)s rooms and %(numSpaces)s spaces|other": "%(count)s rooms and %(numSpaces)s spaces",
|
||||||
"%(count)s rooms and %(numSpaces)s spaces|one": "%(count)s room and %(numSpaces)s spaces",
|
"%(count)s rooms and %(numSpaces)s spaces|one": "%(count)s room and %(numSpaces)s spaces",
|
||||||
"%(count)s rooms and 1 space|other": "%(count)s rooms and 1 space",
|
"%(count)s rooms and 1 space|other": "%(count)s rooms and 1 space",
|
||||||
|
@ -2629,14 +2628,14 @@
|
||||||
"Mark as suggested": "Mark as suggested",
|
"Mark as suggested": "Mark as suggested",
|
||||||
"No results found": "No results found",
|
"No results found": "No results found",
|
||||||
"You may want to try a different search or check for typos.": "You may want to try a different search or check for typos.",
|
"You may want to try a different search or check for typos.": "You may want to try a different search or check for typos.",
|
||||||
"Create room": "Create room",
|
"Your server does not support showing space hierarchies.": "Your server does not support showing space hierarchies.",
|
||||||
"Search names and description": "Search names and description",
|
"Search names and description": "Search names and description",
|
||||||
|
"If you can't find the room you're looking for, ask for an invite or <a>create a new room</a>.": "If you can't find the room you're looking for, ask for an invite or <a>create a new room</a>.",
|
||||||
|
"Create room": "Create room",
|
||||||
"<inviter/> invites you": "<inviter/> invites you",
|
"<inviter/> invites you": "<inviter/> invites you",
|
||||||
"Public space": "Public space",
|
"Public space": "Public space",
|
||||||
"Private space": "Private space",
|
"Private space": "Private space",
|
||||||
"Add existing rooms & spaces": "Add existing rooms & spaces",
|
"Add existing rooms & spaces": "Add existing rooms & spaces",
|
||||||
"Default Rooms": "Default Rooms",
|
|
||||||
"Your server does not support showing space hierarchies.": "Your server does not support showing space hierarchies.",
|
|
||||||
"Your public space <name/>": "Your public space <name/>",
|
"Your public space <name/>": "Your public space <name/>",
|
||||||
"Your private space <name/>": "Your private space <name/>",
|
"Your private space <name/>": "Your private space <name/>",
|
||||||
"Welcome to <name/>": "Welcome to <name/>",
|
"Welcome to <name/>": "Welcome to <name/>",
|
||||||
|
|
Loading…
Reference in a new issue