mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-02-23 05:33:07 +01:00
move room settings in popup window
This commit is contained in:
parent
bcaa783efb
commit
35e05675fa
9 changed files with 102 additions and 167 deletions
|
@ -29,7 +29,7 @@ import { usePowerLevels } from '../../hooks/usePowerLevels';
|
|||
import { copyToClipboard } from '../../utils/dom';
|
||||
import { getOriginBaseUrl, withOriginBaseUrl } from '../../pages/pathUtils';
|
||||
import { markAsRead } from '../../../client/action/notifications';
|
||||
import { openInviteUser } from '../../../client/action/navigation';
|
||||
import { openInviteUser, toggleRoomSettings } from '../../../client/action/navigation';
|
||||
|
||||
type RoomNavItemMenuProps = {
|
||||
room: Room;
|
||||
|
@ -59,7 +59,7 @@ const RoomNavItemMenu = forwardRef<HTMLDivElement, RoomNavItemMenuProps>(
|
|||
};
|
||||
|
||||
const handleRoomSettings = () => {
|
||||
alert('Work In Progress...');
|
||||
toggleRoomSettings(room.roomId);
|
||||
requestClose();
|
||||
};
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ import { useRoomUnread } from '../../state/hooks/unread';
|
|||
import { usePowerLevelsAPI } from '../../hooks/usePowerLevels';
|
||||
import { markAsRead } from '../../../client/action/notifications';
|
||||
import { roomToUnreadAtom } from '../../state/room/roomToUnread';
|
||||
import { openInviteUser } from '../../../client/action/navigation';
|
||||
import { openInviteUser, toggleRoomSettings } from '../../../client/action/navigation';
|
||||
import { copyToClipboard } from '../../utils/dom';
|
||||
|
||||
type RoomMenuProps = {
|
||||
|
@ -82,7 +82,7 @@ const RoomMenu = forwardRef<HTMLDivElement, RoomMenuProps>(
|
|||
};
|
||||
|
||||
const handleRoomSettings = () => {
|
||||
alert('Work In Progress...');
|
||||
toggleRoomSettings(room.roomId);
|
||||
requestClose();
|
||||
};
|
||||
|
||||
|
|
|
@ -9,14 +9,18 @@ import InviteUser from '../invite-user/InviteUser';
|
|||
import Settings from '../settings/Settings';
|
||||
import SpaceSettings from '../space-settings/SpaceSettings';
|
||||
import SpaceManage from '../space-manage/SpaceManage';
|
||||
import RoomSettings from '../room/RoomSettings';
|
||||
|
||||
function Windows() {
|
||||
const [isInviteList, changeInviteList] = useState(false);
|
||||
const [publicRooms, changePublicRooms] = useState({
|
||||
isOpen: false, searchTerm: undefined,
|
||||
isOpen: false,
|
||||
searchTerm: undefined,
|
||||
});
|
||||
const [inviteUser, changeInviteUser] = useState({
|
||||
isOpen: false, roomId: undefined, term: undefined,
|
||||
isOpen: false,
|
||||
roomId: undefined,
|
||||
term: undefined,
|
||||
});
|
||||
|
||||
function openInviteList() {
|
||||
|
@ -49,10 +53,7 @@ function Windows() {
|
|||
|
||||
return (
|
||||
<>
|
||||
<InviteList
|
||||
isOpen={isInviteList}
|
||||
onRequestClose={() => changeInviteList(false)}
|
||||
/>
|
||||
<InviteList isOpen={isInviteList} onRequestClose={() => changeInviteList(false)} />
|
||||
<PublicRooms
|
||||
isOpen={publicRooms.isOpen}
|
||||
searchTerm={publicRooms.searchTerm}
|
||||
|
@ -66,6 +67,7 @@ function Windows() {
|
|||
/>
|
||||
<Settings />
|
||||
<SpaceSettings />
|
||||
<RoomSettings />
|
||||
<SpaceManage />
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -2,22 +2,16 @@ import React, { useState, useEffect } from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import './RoomSettings.scss';
|
||||
|
||||
import { blurOnBubbling } from '../../atoms/button/script';
|
||||
|
||||
import initMatrix from '../../../client/initMatrix';
|
||||
import cons from '../../../client/state/cons';
|
||||
import navigation from '../../../client/state/navigation';
|
||||
import { openInviteUser, toggleRoomSettings } from '../../../client/action/navigation';
|
||||
import { openInviteUser } from '../../../client/action/navigation';
|
||||
import * as roomActions from '../../../client/action/room';
|
||||
|
||||
import Text from '../../atoms/text/Text';
|
||||
import RawIcon from '../../atoms/system-icons/RawIcon';
|
||||
import Header, { TitleWrapper } from '../../atoms/header/Header';
|
||||
import ScrollView from '../../atoms/scroll/ScrollView';
|
||||
import Tabs from '../../atoms/tabs/Tabs';
|
||||
import { MenuHeader, MenuItem } from '../../atoms/context-menu/ContextMenu';
|
||||
import RoomProfile from '../../molecules/room-profile/RoomProfile';
|
||||
import RoomSearch from '../../molecules/room-search/RoomSearch';
|
||||
import RoomNotification from '../../molecules/room-notification/RoomNotification';
|
||||
import RoomVisibility from '../../molecules/room-visibility/RoomVisibility';
|
||||
import RoomAliases from '../../molecules/room-aliases/RoomAliases';
|
||||
|
@ -30,50 +24,51 @@ import RoomEmojis from '../../molecules/room-emojis/RoomEmojis';
|
|||
import UserIC from '../../../../public/res/ic/outlined/user.svg';
|
||||
import SettingsIC from '../../../../public/res/ic/outlined/settings.svg';
|
||||
import EmojiIC from '../../../../public/res/ic/outlined/emoji.svg';
|
||||
import SearchIC from '../../../../public/res/ic/outlined/search.svg';
|
||||
import ShieldUserIC from '../../../../public/res/ic/outlined/shield-user.svg';
|
||||
import LockIC from '../../../../public/res/ic/outlined/lock.svg';
|
||||
import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg';
|
||||
import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg';
|
||||
import ChevronTopIC from '../../../../public/res/ic/outlined/chevron-top.svg';
|
||||
import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
|
||||
|
||||
import { useForceUpdate } from '../../hooks/useForceUpdate';
|
||||
import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog';
|
||||
import PopupWindow from '../../molecules/popup-window/PopupWindow';
|
||||
import IconButton from '../../atoms/button/IconButton';
|
||||
|
||||
const tabText = {
|
||||
GENERAL: 'General',
|
||||
SEARCH: 'Search',
|
||||
MEMBERS: 'Members',
|
||||
EMOJIS: 'Emojis',
|
||||
PERMISSIONS: 'Permissions',
|
||||
SECURITY: 'Security',
|
||||
};
|
||||
|
||||
const tabItems = [{
|
||||
iconSrc: SettingsIC,
|
||||
text: tabText.GENERAL,
|
||||
disabled: false,
|
||||
}, {
|
||||
iconSrc: SearchIC,
|
||||
text: tabText.SEARCH,
|
||||
disabled: false,
|
||||
}, {
|
||||
iconSrc: UserIC,
|
||||
text: tabText.MEMBERS,
|
||||
disabled: false,
|
||||
}, {
|
||||
iconSrc: EmojiIC,
|
||||
text: tabText.EMOJIS,
|
||||
disabled: false,
|
||||
}, {
|
||||
iconSrc: ShieldUserIC,
|
||||
text: tabText.PERMISSIONS,
|
||||
disabled: false,
|
||||
}, {
|
||||
iconSrc: LockIC,
|
||||
text: tabText.SECURITY,
|
||||
disabled: false,
|
||||
}];
|
||||
const tabItems = [
|
||||
{
|
||||
iconSrc: SettingsIC,
|
||||
text: tabText.GENERAL,
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
iconSrc: UserIC,
|
||||
text: tabText.MEMBERS,
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
iconSrc: EmojiIC,
|
||||
text: tabText.EMOJIS,
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
iconSrc: ShieldUserIC,
|
||||
text: tabText.PERMISSIONS,
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
iconSrc: LockIC,
|
||||
text: tabText.SECURITY,
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
function GeneralSettings({ roomId }) {
|
||||
const mx = initMatrix.matrixClient;
|
||||
|
@ -84,11 +79,7 @@ function GeneralSettings({ roomId }) {
|
|||
<>
|
||||
<div className="room-settings__card">
|
||||
<MenuHeader>Options</MenuHeader>
|
||||
<MenuItem
|
||||
disabled={!canInvite}
|
||||
onClick={() => openInviteUser(roomId)}
|
||||
iconSrc={AddUserIC}
|
||||
>
|
||||
<MenuItem disabled={!canInvite} onClick={() => openInviteUser(roomId)} iconSrc={AddUserIC}>
|
||||
Invite
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
|
@ -98,7 +89,7 @@ function GeneralSettings({ roomId }) {
|
|||
'Leave room',
|
||||
`Are you sure that you want to leave "${room.name}" room?`,
|
||||
'Leave',
|
||||
'danger',
|
||||
'danger'
|
||||
);
|
||||
if (!isConfirmed) return;
|
||||
roomActions.leave(roomId);
|
||||
|
@ -146,54 +137,52 @@ SecuritySettings.propTypes = {
|
|||
roomId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
function RoomSettings({ roomId }) {
|
||||
const [, forceUpdate] = useForceUpdate();
|
||||
function useWindowToggle(setSelectedTab) {
|
||||
const [window, setWindow] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
const openRoomSettings = (roomId, tab) => {
|
||||
setWindow({ roomId, tabText });
|
||||
const tabItem = tabItems.find((item) => item.text === tab);
|
||||
if (tabItem) setSelectedTab(tabItem);
|
||||
};
|
||||
navigation.on(cons.events.navigation.ROOM_SETTINGS_TOGGLED, openRoomSettings);
|
||||
return () => {
|
||||
navigation.removeListener(cons.events.navigation.ROOM_SETTINGS_TOGGLED, openRoomSettings);
|
||||
};
|
||||
}, [setSelectedTab]);
|
||||
|
||||
const requestClose = () => setWindow(null);
|
||||
|
||||
return [window, requestClose];
|
||||
}
|
||||
|
||||
function RoomSettings() {
|
||||
const [selectedTab, setSelectedTab] = useState(tabItems[0]);
|
||||
const [window, requestClose] = useWindowToggle(setSelectedTab);
|
||||
const isOpen = window !== null;
|
||||
const roomId = window?.roomId;
|
||||
const room = initMatrix.matrixClient.getRoom(roomId);
|
||||
|
||||
const handleTabChange = (tabItem) => {
|
||||
setSelectedTab(tabItem);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let mounted = true;
|
||||
const settingsToggle = (isVisible, tab) => {
|
||||
if (!mounted) return;
|
||||
if (isVisible) {
|
||||
const tabItem = tabItems.find((item) => item.text === tab);
|
||||
if (tabItem) setSelectedTab(tabItem);
|
||||
forceUpdate();
|
||||
} else setTimeout(() => forceUpdate(), 200);
|
||||
};
|
||||
navigation.on(cons.events.navigation.ROOM_SETTINGS_TOGGLED, settingsToggle);
|
||||
return () => {
|
||||
mounted = false;
|
||||
navigation.removeListener(cons.events.navigation.ROOM_SETTINGS_TOGGLED, settingsToggle);
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (!navigation.isRoomSettings) return null;
|
||||
|
||||
return (
|
||||
<div className="room-settings">
|
||||
<ScrollView autoHide>
|
||||
<PopupWindow
|
||||
isOpen={isOpen}
|
||||
className="room-settings"
|
||||
title={
|
||||
<Text variant="s1" weight="medium" primary>
|
||||
{isOpen && room.name}
|
||||
<span style={{ color: 'var(--tc-surface-low)' }}> — room settings</span>
|
||||
</Text>
|
||||
}
|
||||
contentOptions={<IconButton src={CrossIC} onClick={requestClose} tooltip="Close" />}
|
||||
onRequestClose={requestClose}
|
||||
>
|
||||
{isOpen && (
|
||||
<div className="room-settings__content">
|
||||
<Header>
|
||||
<button
|
||||
className="room-settings__header-btn"
|
||||
onClick={() => toggleRoomSettings()}
|
||||
type="button"
|
||||
onMouseUp={(e) => blurOnBubbling(e, '.room-settings__header-btn')}
|
||||
>
|
||||
<TitleWrapper>
|
||||
<Text variant="s1" weight="medium" primary>
|
||||
{`${room.name}`}
|
||||
<span style={{ color: 'var(--tc-surface-low)' }}> — room settings</span>
|
||||
</Text>
|
||||
</TitleWrapper>
|
||||
<RawIcon size="small" src={ChevronTopIC} />
|
||||
</button>
|
||||
</Header>
|
||||
<RoomProfile roomId={roomId} />
|
||||
<Tabs
|
||||
items={tabItems}
|
||||
|
@ -202,21 +191,16 @@ function RoomSettings({ roomId }) {
|
|||
/>
|
||||
<div className="room-settings__cards-wrapper">
|
||||
{selectedTab.text === tabText.GENERAL && <GeneralSettings roomId={roomId} />}
|
||||
{selectedTab.text === tabText.SEARCH && <RoomSearch roomId={roomId} />}
|
||||
{selectedTab.text === tabText.MEMBERS && <RoomMembers roomId={roomId} />}
|
||||
{selectedTab.text === tabText.EMOJIS && <RoomEmojis roomId={roomId} />}
|
||||
{selectedTab.text === tabText.PERMISSIONS && <RoomPermissions roomId={roomId} />}
|
||||
{selectedTab.text === tabText.SECURITY && <SecuritySettings roomId={roomId} />}
|
||||
</div>
|
||||
</div>
|
||||
</ScrollView>
|
||||
</div>
|
||||
)}
|
||||
</PopupWindow>
|
||||
);
|
||||
}
|
||||
|
||||
RoomSettings.propTypes = {
|
||||
roomId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default RoomSettings;
|
||||
export { tabText };
|
||||
|
|
|
@ -2,59 +2,18 @@
|
|||
@use '../../partials/flex';
|
||||
|
||||
.room-settings {
|
||||
height: 100%;
|
||||
& .scrollbar {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
& .header {
|
||||
padding: 0 var(--sp-extra-tight);
|
||||
}
|
||||
|
||||
&__header-btn {
|
||||
min-width: 0;
|
||||
@extend .cp-fx__row--s-c;
|
||||
@include dir.side(margin, 0, auto);
|
||||
padding: var(--sp-ultra-tight) var(--sp-extra-tight);
|
||||
border-radius: calc(var(--bo-radius) / 2);
|
||||
cursor: pointer;
|
||||
|
||||
@media (hover:hover) {
|
||||
&:hover {
|
||||
background-color: var(--bg-surface-hover);
|
||||
box-shadow: var(--bs-surface-outline);
|
||||
}
|
||||
}
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: var(--bg-surface-active);
|
||||
box-shadow: var(--bs-surface-outline);
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
padding-bottom: calc(2 * var(--sp-extra-loose));
|
||||
|
||||
& .room-profile {
|
||||
margin: var(--sp-extra-loose);
|
||||
}
|
||||
}
|
||||
|
||||
& .tabs {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 999;
|
||||
width: 100%;
|
||||
& .pw {
|
||||
background-color: var(--bg-surface-low);
|
||||
box-shadow: 0 -4px 0 var(--bg-surface-low),
|
||||
inset 0 -1px 0 var(--bg-surface-border);
|
||||
|
||||
&__content {
|
||||
padding: 0 var(--sp-normal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
& .room-profile {
|
||||
padding: var(--sp-loose) var(--sp-extra-loose);
|
||||
}
|
||||
|
||||
& .tabs__content {
|
||||
padding: 0 var(--sp-normal);
|
||||
}
|
||||
|
||||
&__cards-wrapper {
|
||||
padding: 0 var(--sp-normal);
|
||||
@include dir.side(padding, var(--sp-normal), var(--sp-extra-tight));
|
||||
|
@ -75,7 +34,7 @@
|
|||
|
||||
.room-settings .room-permissions__card,
|
||||
.room-settings .room-search__form,
|
||||
.room-settings .room-search__result-item ,
|
||||
.room-settings .room-search__result-item,
|
||||
.room-settings .room-members {
|
||||
@extend .room-settings__card;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React, { useEffect, useRef } from 'react';
|
||||
import './Client.scss';
|
||||
|
||||
import Navigation from '../../organisms/navigation/Navigation';
|
||||
import ReusableContextMenu from '../../atoms/context-menu/ReusableContextMenu';
|
||||
import Windows from '../../organisms/pw/Windows';
|
||||
import Dialogs from '../../organisms/pw/Dialogs';
|
||||
|
|
|
@ -52,10 +52,11 @@ export function openSpaceAddExisting(roomId) {
|
|||
});
|
||||
}
|
||||
|
||||
export function toggleRoomSettings(tabText) {
|
||||
export function toggleRoomSettings(roomId, tabText) {
|
||||
appDispatcher.dispatch({
|
||||
type: cons.actions.navigation.TOGGLE_ROOM_SETTINGS,
|
||||
tabText,
|
||||
roomId,
|
||||
tabText
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { openSearch, toggleRoomSettings } from '../action/navigation';
|
||||
import { openSearch } from '../action/navigation';
|
||||
import navigation from '../state/navigation';
|
||||
import { markAsRead } from '../action/notifications';
|
||||
|
||||
|
@ -53,10 +53,6 @@ function listenKeyboard(event) {
|
|||
if (navigation.isRawModalVisible) return;
|
||||
|
||||
if (event.key === 'Escape') {
|
||||
if (navigation.isRoomSettings) {
|
||||
toggleRoomSettings();
|
||||
return;
|
||||
}
|
||||
if (navigation.selectedRoomId) {
|
||||
markAsRead(navigation.selectedRoomId);
|
||||
return;
|
||||
|
|
|
@ -13,7 +13,6 @@ class Navigation extends EventEmitter {
|
|||
this.selectedSpacePath = [cons.tabs.HOME];
|
||||
|
||||
this.selectedRoomId = null;
|
||||
this.isRoomSettings = false;
|
||||
this.recentRooms = [];
|
||||
|
||||
this.spaceToRoom = new Map();
|
||||
|
@ -85,10 +84,6 @@ class Navigation extends EventEmitter {
|
|||
this.removeRecentRoom(prevSelectedRoomId);
|
||||
this.addRecentRoom(prevSelectedRoomId);
|
||||
this.removeRecentRoom(this.selectedRoomId);
|
||||
if (this.isRoomSettings && typeof this.selectedRoomId === 'string') {
|
||||
this.isRoomSettings = !this.isRoomSettings;
|
||||
this.emit(cons.events.navigation.ROOM_SETTINGS_TOGGLED, this.isRoomSettings);
|
||||
}
|
||||
this.emit(
|
||||
cons.events.navigation.ROOM_SELECTED,
|
||||
this.selectedRoomId,
|
||||
|
@ -308,11 +303,10 @@ class Navigation extends EventEmitter {
|
|||
this.emit(cons.events.navigation.SPACE_ADDEXISTING_OPENED, action.roomId);
|
||||
},
|
||||
[cons.actions.navigation.TOGGLE_ROOM_SETTINGS]: () => {
|
||||
this.isRoomSettings = !this.isRoomSettings;
|
||||
this.emit(
|
||||
cons.events.navigation.ROOM_SETTINGS_TOGGLED,
|
||||
this.isRoomSettings,
|
||||
action.tabText,
|
||||
action.roomId,
|
||||
action.tabText
|
||||
);
|
||||
},
|
||||
[cons.actions.navigation.OPEN_SHORTCUT_SPACES]: () => {
|
||||
|
|
Loading…
Reference in a new issue