diff --git a/public/res/ic/filled/star.svg b/public/res/ic/filled/star.svg new file mode 100644 index 0000000..378c891 --- /dev/null +++ b/public/res/ic/filled/star.svg @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/public/res/ic/outlined/star.svg b/public/res/ic/outlined/star.svg new file mode 100644 index 0000000..290f159 --- /dev/null +++ b/public/res/ic/outlined/star.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/src/app/molecules/room-selector/RoomSelector.scss b/src/app/molecules/room-selector/RoomSelector.scss index 9b40fcb..ae3144b 100644 --- a/src/app/molecules/room-selector/RoomSelector.scss +++ b/src/app/molecules/room-selector/RoomSelector.scss @@ -83,7 +83,7 @@ margin: 0 !important; } - & .ic-btn-surface { + & .ic-btn { padding: 6px; border-radius: calc(var(--bo-radius) / 2); } diff --git a/src/app/organisms/navigation/Drawer.jsx b/src/app/organisms/navigation/Drawer.jsx index f8c53ea..b76347e 100644 --- a/src/app/organisms/navigation/Drawer.jsx +++ b/src/app/organisms/navigation/Drawer.jsx @@ -1,8 +1,10 @@ import React, { useState, useEffect } from 'react'; import './Drawer.scss'; +import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; +import { selectTab, selectSpace } from '../../../client/action/navigation'; import ScrollView from '../../atoms/scroll/ScrollView'; @@ -12,34 +14,42 @@ import Home from './Home'; import Directs from './Directs'; function Drawer() { - const [selectedTab, setSelectedTab] = useState('home'); + const [selectedTab, setSelectedTab] = useState(navigation.selectedTab); const [spaceId, setSpaceId] = useState(navigation.selectedSpaceId); - function onTabChanged(tabId) { + function onTabSelected(tabId) { setSelectedTab(tabId); } function onSpaceSelected(roomId) { setSpaceId(roomId); } + function onRoomLeaved(roomId) { + const lRoomIndex = navigation.selectedSpacePath.indexOf(roomId); + if (lRoomIndex === -1) return; + if (lRoomIndex === 0) selectTab(cons.tabs.HOME); + else selectSpace(navigation.selectedSpacePath[lRoomIndex - 1]); + } useEffect(() => { - navigation.on(cons.events.navigation.TAB_CHANGED, onTabChanged); + navigation.on(cons.events.navigation.TAB_SELECTED, onTabSelected); navigation.on(cons.events.navigation.SPACE_SELECTED, onSpaceSelected); + initMatrix.roomList.on(cons.events.roomList.ROOM_LEAVED, onRoomLeaved); return () => { - navigation.removeListener(cons.events.navigation.TAB_CHANGED, onTabChanged); + navigation.removeListener(cons.events.navigation.TAB_SELECTED, onTabSelected); navigation.removeListener(cons.events.navigation.SPACE_SELECTED, onSpaceSelected); + initMatrix.roomList.removeListener(cons.events.roomList.ROOM_LEAVED, onRoomLeaved); }; }, []); return (
- {selectedTab === 'home' && } + {selectedTab !== cons.tabs.DIRECTS && }
{ - selectedTab === 'home' + selectedTab !== cons.tabs.DIRECTS ? : } diff --git a/src/app/organisms/navigation/Drawer.scss b/src/app/organisms/navigation/Drawer.scss index b240ac3..e93761a 100644 --- a/src/app/organisms/navigation/Drawer.scss +++ b/src/app/organisms/navigation/Drawer.scss @@ -18,6 +18,10 @@ border-left: 1px solid var(--bg-surface-border); } + & .header__title-wrapper .text { + font-weight: 500; + } + &__content-wrapper { @extend .drawer-flexItem; @extend .drawer-flexBox; diff --git a/src/app/organisms/navigation/DrawerBreadcrumb.jsx b/src/app/organisms/navigation/DrawerBreadcrumb.jsx index 4df5a6d..e784362 100644 --- a/src/app/organisms/navigation/DrawerBreadcrumb.jsx +++ b/src/app/organisms/navigation/DrawerBreadcrumb.jsx @@ -1,4 +1,5 @@ -import React, { useState, useEffect, useRef } from 'react'; +import React, { useEffect, useRef } from 'react'; +import PropTypes from 'prop-types'; import './DrawerBreadcrumb.scss'; import initMatrix from '../../../client/initMatrix'; @@ -13,50 +14,47 @@ import ScrollView from '../../atoms/scroll/ScrollView'; import ChevronRightIC from '../../../../public/res/ic/outlined/chevron-right.svg'; -function DrawerBreadcrumb() { - const [, forceUpdate] = useState({}); +function DrawerBreadcrumb({ spaceId }) { const scrollRef = useRef(null); const mx = initMatrix.matrixClient; const spacePath = navigation.selectedSpacePath; - function onSpaceSelected() { - forceUpdate({}); + useEffect(() => { requestAnimationFrame(() => { if (scrollRef?.current === null) return; scrollRef.current.scrollLeft = scrollRef.current.scrollWidth; }); - } + }, [spaceId]); - useEffect(() => { - navigation.on(cons.events.navigation.SPACE_SELECTED, onSpaceSelected); - return () => { - navigation.removeListener(cons.events.navigation.SPACE_SELECTED, onSpaceSelected); - }; - }, []); - - if (spacePath.length === 0) return null; + if (spacePath.length === 1) return null; return (
- { - spacePath.map((spaceId, index) => ( - - - + ); + } + return ( + - { mx.getRoom(spaceId).name } - - - )) + + + + ); + }) }
@@ -65,4 +63,12 @@ function DrawerBreadcrumb() { ); } +DrawerBreadcrumb.defaultProps = { + spaceId: null, +}; + +DrawerBreadcrumb.propTypes = { + spaceId: PropTypes.string, +}; + export default DrawerBreadcrumb; diff --git a/src/app/organisms/navigation/DrawerHeader.jsx b/src/app/organisms/navigation/DrawerHeader.jsx index 686d476..220633c 100644 --- a/src/app/organisms/navigation/DrawerHeader.jsx +++ b/src/app/organisms/navigation/DrawerHeader.jsx @@ -1,11 +1,12 @@ -import React from 'react'; +import React, { useState } from 'react'; import PropTypes from 'prop-types'; import initMatrix from '../../../client/initMatrix'; +import cons from '../../../client/state/cons'; import { - selectSpace, openPublicRooms, openCreateRoom, openInviteUser, + openPublicRooms, openCreateRoom, openInviteUser, } from '../../../client/action/navigation'; -import navigation from '../../../client/state/navigation'; +import { createSpaceShortcut, deleteSpaceShortcut } from '../../../client/action/room'; import Text from '../../atoms/text/Text'; import Header, { TitleWrapper } from '../../atoms/header/Header'; @@ -15,32 +16,37 @@ import ContextMenu, { MenuItem, MenuHeader } from '../../atoms/context-menu/Cont import PlusIC from '../../../../public/res/ic/outlined/plus.svg'; import HashPlusIC from '../../../../public/res/ic/outlined/hash-plus.svg'; import HashSearchIC from '../../../../public/res/ic/outlined/hash-search.svg'; -import ChevronLeftIC from '../../../../public/res/ic/outlined/chevron-left.svg'; +import StarIC from '../../../../public/res/ic/outlined/star.svg'; +import FilledStarIC from '../../../../public/res/ic/filled/star.svg'; function DrawerHeader({ selectedTab, spaceId }) { + const [, forceUpdate] = useState({}); const mx = initMatrix.matrixClient; - const tabName = selectedTab === 'home' ? 'Home' : 'Direct messages'; + const tabName = selectedTab !== cons.tabs.DIRECTS ? 'Home' : 'Direct messages'; const room = mx.getRoom(spaceId); - const spaceName = selectedTab === 'dm' ? null : (room?.name || null); - - function handleBackClick() { - const spacePath = navigation.selectedSpacePath; - if (spacePath.length === 1) { - selectSpace(null); - return; - } - selectSpace(spacePath[spacePath.length - 2]); - } + const spaceName = selectedTab === cons.tabs.DIRECTS ? null : (room?.name || null); return (
{spaceName || tabName} - { spaceName && } - { selectedTab === 'dm' && openInviteUser()} tooltip="Start DM" src={PlusIC} size="normal" /> } - { selectSpace !== 'dm' && !spaceName && ( + {spaceName && ( + { + if (initMatrix.roomList.spaceShortcut.has(spaceId)) deleteSpaceShortcut(spaceId); + else createSpaceShortcut(spaceId); + forceUpdate({}); + }} + /> + )} + { selectedTab === cons.tabs.DIRECTS && openInviteUser()} tooltip="Start DM" src={PlusIC} size="normal" /> } + { selectedTab !== cons.tabs.DIRECTS && !spaceName && ( <> ( diff --git a/src/app/organisms/navigation/Selector.jsx b/src/app/organisms/navigation/Selector.jsx index 9430bb1..0ddc127 100644 --- a/src/app/organisms/navigation/Selector.jsx +++ b/src/app/organisms/navigation/Selector.jsx @@ -5,20 +5,25 @@ import PropTypes from 'prop-types'; import initMatrix from '../../../client/initMatrix'; import { doesRoomHaveUnread } from '../../../util/matrixUtil'; import navigation from '../../../client/state/navigation'; +import { createSpaceShortcut, deleteSpaceShortcut } from '../../../client/action/room'; +import IconButton from '../../atoms/button/IconButton'; import RoomSelector from '../../molecules/room-selector/RoomSelector'; import HashIC from '../../../../public/res/ic/outlined/hash.svg'; import HashLockIC from '../../../../public/res/ic/outlined/hash-lock.svg'; import SpaceIC from '../../../../public/res/ic/outlined/space.svg'; import SpaceLockIC from '../../../../public/res/ic/outlined/space-lock.svg'; +import StarIC from '../../../../public/res/ic/outlined/star.svg'; +import FilledStarIC from '../../../../public/res/ic/filled/star.svg'; function Selector({ roomId, isDM, drawerPostie, onClick, }) { const mx = initMatrix.matrixClient; const room = mx.getRoom(roomId); - const imageSrc = room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null; + let imageSrc = room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null; + if (imageSrc === null) imageSrc = room.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null; const [isSelected, setIsSelected] = useState(navigation.selectedRoomId === roomId); const [, forceUpdate] = useState({}); @@ -60,6 +65,23 @@ function Selector({ notificationCount={room.getUnreadNotificationCount('total') || 0} isAlert={room.getUnreadNotificationCount('highlight') !== 0} onClick={onClick} + options={( + !room.isSpaceRoom() + ? null + : ( + { + if (initMatrix.roomList.spaceShortcut.has(roomId)) deleteSpaceShortcut(roomId); + else createSpaceShortcut(roomId); + forceUpdate({}); + }} + /> + ) + )} /> ); } diff --git a/src/app/organisms/navigation/SideBar.jsx b/src/app/organisms/navigation/SideBar.jsx index 1468bc6..b95636f 100644 --- a/src/app/organisms/navigation/SideBar.jsx +++ b/src/app/organisms/navigation/SideBar.jsx @@ -6,7 +6,7 @@ import cons from '../../../client/state/cons'; import colorMXID from '../../../util/colorMXID'; import logout from '../../../client/action/logout'; import { - changeTab, openInviteList, openPublicRooms, openSettings, + selectTab, openInviteList, openPublicRooms, openSettings, } from '../../../client/action/navigation'; import navigation from '../../../client/state/navigation'; @@ -55,29 +55,37 @@ function ProfileAvatarMenu() { } function SideBar() { - const totalInviteCount = () => initMatrix.roomList.inviteRooms.size - + initMatrix.roomList.inviteSpaces.size - + initMatrix.roomList.inviteDirects.size; + const { roomList } = initMatrix; + const mx = initMatrix.matrixClient; + const totalInviteCount = () => roomList.inviteRooms.size + + roomList.inviteSpaces.size + + roomList.inviteDirects.size; const [totalInvites, updateTotalInvites] = useState(totalInviteCount()); - const [selectedTab, setSelectedTab] = useState('home'); + const [selectedTab, setSelectedTab] = useState(navigation.selectedTab); + const [, forceUpdate] = useState({}); - function onTabChanged(tabId) { + function onTabSelected(tabId) { setSelectedTab(tabId); } function onInviteListChange() { updateTotalInvites(totalInviteCount()); } + function onSpaceShortcutUpdated() { + forceUpdate({}); + } useEffect(() => { - navigation.on(cons.events.navigation.TAB_CHANGED, onTabChanged); + navigation.on(cons.events.navigation.TAB_SELECTED, onTabSelected); + roomList.on(cons.events.roomList.SPACE_SHORTCUT_UPDATED, onSpaceShortcutUpdated); initMatrix.roomList.on( cons.events.roomList.INVITELIST_UPDATED, onInviteListChange, ); return () => { - navigation.removeListener(cons.events.navigation.TAB_CHANGED, onTabChanged); + navigation.removeListener(cons.events.navigation.TAB_SELECTED, onTabSelected); + roomList.removeListener(cons.events.roomList.SPACE_SHORTCUT_UPDATED, onSpaceShortcutUpdated); initMatrix.roomList.removeListener( cons.events.roomList.INVITELIST_UPDATED, onInviteListChange, @@ -91,12 +99,30 @@ function SideBar() {
- changeTab('home')} tooltip="Home" iconSrc={HomeIC} /> - changeTab('dm')} tooltip="People" iconSrc={UserIC} /> + selectTab(cons.tabs.HOME)} tooltip="Home" iconSrc={HomeIC} /> + selectTab(cons.tabs.DIRECTS)} tooltip="People" iconSrc={UserIC} /> openPublicRooms()} tooltip="Public rooms" iconSrc={HashSearchIC} />
-
+
+ { + [...roomList.spaceShortcut].map((shortcut) => { + const sRoomId = shortcut; + const room = mx.getRoom(sRoomId); + return ( + selectTab(shortcut)} + /> + ); + }) + } +
diff --git a/src/app/organisms/navigation/SideBar.scss b/src/app/organisms/navigation/SideBar.scss index 09641fc..48970fb 100644 --- a/src/app/organisms/navigation/SideBar.scss +++ b/src/app/organisms/navigation/SideBar.scss @@ -44,7 +44,7 @@ var(--bg-surface-low), var(--bg-surface-low-transparent)); position: sticky; - bottom: 0; + bottom: -1px; left: 0; } } diff --git a/src/app/organisms/room/PeopleDrawer.jsx b/src/app/organisms/room/PeopleDrawer.jsx index 2a7b18d..ca975d1 100644 --- a/src/app/organisms/room/PeopleDrawer.jsx +++ b/src/app/organisms/room/PeopleDrawer.jsx @@ -18,23 +18,15 @@ import PeopleSelector from '../../molecules/people-selector/PeopleSelector'; import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg'; function getPowerLabel(powerLevel) { - switch (powerLevel) { - case 100: - return 'Admin'; - case 50: - return 'Mod'; - default: - return null; - } + if (powerLevel > 9000) return 'Goku'; + if (powerLevel > 100) return 'Founder'; + if (powerLevel === 100) return 'Admin'; + if (powerLevel >= 50) return 'Mod'; + return null; } -function compare(m1, m2) { - let aName = m1.name; - let bName = m2.name; - - // remove "#" from the room name - // To ignore it in sorting - aName = aName.replaceAll('#', ''); - bName = bName.replaceAll('#', ''); +function AtoZ(m1, m2) { + const aName = m1.name; + const bName = m2.name; if (aName.toLowerCase() < bName.toLowerCase()) { return -1; @@ -45,25 +37,18 @@ function compare(m1, m2) { return 0; } function sortByPowerLevel(m1, m2) { - let pl1 = String(m1.powerLevel); - let pl2 = String(m2.powerLevel); + const pl1 = m1.powerLevel; + const pl2 = m2.powerLevel; - if (pl1 === '100') pl1 = '90.9'; - if (pl2 === '100') pl2 = '90.9'; - - if (pl1.toLowerCase() > pl2.toLowerCase()) { - return -1; - } - if (pl1.toLowerCase() < pl2.toLowerCase()) { - return 1; - } + if (pl1 > pl2) return -1; + if (pl1 < pl2) return 1; return 0; } function PeopleDrawer({ roomId }) { const PER_PAGE_MEMBER = 50; const room = initMatrix.matrixClient.getRoom(roomId); - const totalMemberList = room.getJoinedMembers().sort(compare).sort(sortByPowerLevel); + const totalMemberList = room.getJoinedMembers().sort(AtoZ).sort(sortByPowerLevel); const [memberList, updateMemberList] = useState([]); let isRoomChanged = false; @@ -75,7 +60,7 @@ function PeopleDrawer({ roomId }) { updateMemberList(totalMemberList.slice(0, PER_PAGE_MEMBER)); room.loadMembersIfNeeded().then(() => { if (isRoomChanged) return; - const newTotalMemberList = room.getJoinedMembers().sort(compare).sort(sortByPowerLevel); + const newTotalMemberList = room.getJoinedMembers().sort(AtoZ).sort(sortByPowerLevel); updateMemberList(newTotalMemberList.slice(0, PER_PAGE_MEMBER)); }); diff --git a/src/app/organisms/room/RoomViewCmdBar.jsx b/src/app/organisms/room/RoomViewCmdBar.jsx index 7f8f809..329d46a 100644 --- a/src/app/organisms/room/RoomViewCmdBar.jsx +++ b/src/app/organisms/room/RoomViewCmdBar.jsx @@ -10,6 +10,7 @@ import cons from '../../../client/state/cons'; import { toggleMarkdown } from '../../../client/action/settings'; import * as roomActions from '../../../client/action/room'; import { + selectTab, selectRoom, openCreateRoom, openPublicRooms, @@ -357,7 +358,8 @@ function RoomViewCmdBar({ roomId, roomTimeline, viewEvent }) { } function fireCmd(myCmd) { if (myCmd.prefix.match(/^>[*#@]$/)) { - selectRoom(myCmd.result.roomId); + if (cmd.prefix === '>*') selectTab(myCmd.result.roomId); + else selectRoom(myCmd.result.roomId); viewEvent.emit('cmd_fired'); } if (myCmd.prefix === '/') { diff --git a/src/client/action/navigation.js b/src/client/action/navigation.js index bf560d8..5fa1304 100644 --- a/src/client/action/navigation.js +++ b/src/client/action/navigation.js @@ -1,9 +1,9 @@ import appDispatcher from '../dispatcher'; import cons from '../state/cons'; -function changeTab(tabId) { +function selectTab(tabId) { appDispatcher.dispatch({ - type: cons.actions.navigation.CHANGE_TAB, + type: cons.actions.navigation.SELECT_TAB, tabId, }); } @@ -78,7 +78,7 @@ function openReadReceipts(roomId, eventId) { } export { - changeTab, + selectTab, selectSpace, selectRoom, togglePeopleDrawer, diff --git a/src/client/action/room.js b/src/client/action/room.js index 407a9e3..08e73e2 100644 --- a/src/client/action/room.js +++ b/src/client/action/room.js @@ -190,7 +190,22 @@ async function invite(roomId, userId) { } } +function createSpaceShortcut(roomId) { + appDispatcher.dispatch({ + type: cons.actions.room.CREATE_SPACE_SHORTCUT, + roomId, + }); +} + +function deleteSpaceShortcut(roomId) { + appDispatcher.dispatch({ + type: cons.actions.room.DELETE_SPACE_SHORTCUT, + roomId, + }); +} + export { join, leave, create, invite, + createSpaceShortcut, deleteSpaceShortcut, }; diff --git a/src/client/state/RoomList.js b/src/client/state/RoomList.js index 4e88adc..a47bf46 100644 --- a/src/client/state/RoomList.js +++ b/src/client/state/RoomList.js @@ -9,6 +9,8 @@ class RoomList extends EventEmitter { this.mDirects = this.getMDirects(); this.roomIdToParents = new Map(); + this.spaceShortcut = new Set(); + this.inviteDirects = new Set(); this.inviteSpaces = new Set(); this.inviteRooms = new Set(); @@ -20,11 +22,18 @@ class RoomList extends EventEmitter { this.processingRooms = new Map(); this._populateRooms(); + this._populateSpaceShortcut(); this._listenEvents(); appDispatcher.register(this.roomActions.bind(this)); } + _updateSpaceShortcutData(shortcutList) { + const spaceContent = this.matrixClient.getAccountData(cons['in.cinny.spaces'])?.getContent() || {}; + spaceContent.shortcut = shortcutList; + this.matrixClient.setAccountData(cons['in.cinny.spaces'], spaceContent); + } + getSpaceChildren(roomId) { const space = this.matrixClient.getRoom(roomId); const mSpaceChild = space?.currentState.getStateEvents('m.space.child'); @@ -64,6 +73,12 @@ class RoomList extends EventEmitter { spaceChildren?.forEach((childRoomId) => { this.removeFromRoomIdToParents(childRoomId, roomId); }); + + if (this.spaceShortcut.has(roomId)) { + // if delete space has shortcut remove it. + this.spaceShortcut.delete(roomId); + this._updateSpaceShortcutData([...this.spaceShortcut]); + } } roomActions(action) { @@ -106,6 +121,18 @@ class RoomList extends EventEmitter { }); } }, + [cons.actions.room.CREATE_SPACE_SHORTCUT]: () => { + if (this.spaceShortcut.has(action.roomId)) return; + this.spaceShortcut.add(action.roomId); + this._updateSpaceShortcutData([...this.spaceShortcut]); + this.emit(cons.events.roomList.SPACE_SHORTCUT_UPDATED, action.roomId); + }, + [cons.actions.room.DELETE_SPACE_SHORTCUT]: () => { + if (!this.spaceShortcut.has(action.roomId)) return; + this.spaceShortcut.delete(action.roomId); + this._updateSpaceShortcutData([...this.spaceShortcut]); + this.emit(cons.events.roomList.SPACE_SHORTCUT_UPDATED, action.roomId); + }, }; actions[action.type]?.(); } @@ -125,6 +152,21 @@ class RoomList extends EventEmitter { return mDirectsId; } + _populateSpaceShortcut() { + this.spaceShortcut.clear(); + const spacesContent = this.matrixClient.getAccountData(cons['in.cinny.spaces'])?.getContent(); + + if (spacesContent && Array.isArray(spacesContent?.shortcut)) { + spacesContent.shortcut.forEach((shortcut) => { + if (this.spaces.has(shortcut)) this.spaceShortcut.add(shortcut); + }); + if (spacesContent.shortcut.length !== this.spaceShortcut.size) { + // update shortcut list from account data if shortcut space doesn't exist. + this._updateSpaceShortcutData([...this.spaceShortcut]); + } + } + } + _populateRooms() { this.directs.clear(); this.roomIdToParents.clear(); @@ -166,6 +208,12 @@ class RoomList extends EventEmitter { _listenEvents() { // Update roomList when m.direct changes this.matrixClient.on('accountData', (event) => { + if (event.getType() === cons['in.cinny.spaces']) { + this._populateSpaceShortcut(); + this.emit(cons.events.roomList.SPACE_SHORTCUT_UPDATED); + return; + } + if (event.getType() !== 'm.direct') return; const latestMDirects = this.getMDirects(); diff --git a/src/client/state/cons.js b/src/client/state/cons.js index e8b8d15..7587120 100644 --- a/src/client/state/cons.js +++ b/src/client/state/cons.js @@ -6,9 +6,14 @@ const cons = { BASE_URL: 'cinny_hs_base_url', }, DEVICE_DISPLAY_NAME: 'Cinny Web', + 'in.cinny.spaces': 'in.cinny.spaces', + tabs: { + HOME: 'home', + DIRECTS: 'dm', + }, actions: { navigation: { - CHANGE_TAB: 'CHANGE_TAB', + SELECT_TAB: 'SELECT_TAB', SELECT_SPACE: 'SELECT_SPACE', SELECT_ROOM: 'SELECT_ROOM', TOGGLE_PEOPLE_DRAWER: 'TOGGLE_PEOPLE_DRAWER', @@ -24,6 +29,8 @@ const cons = { JOIN: 'JOIN', LEAVE: 'LEAVE', CREATE: 'CREATE', + CREATE_SPACE_SHORTCUT: 'CREATE_SPACE_SHORTCUT', + DELETE_SPACE_SHORTCUT: 'DELETE_SPACE_SHORTCUT', error: { CREATE: 'ERROR_CREATE', }, @@ -34,7 +41,7 @@ const cons = { }, events: { navigation: { - TAB_CHANGED: 'TAB_CHANGED', + TAB_SELECTED: 'TAB_SELECTED', SPACE_SELECTED: 'SPACE_SELECTED', ROOM_SELECTED: 'ROOM_SELECTED', PEOPLE_DRAWER_TOGGLED: 'PEOPLE_DRAWER_TOGGLED', @@ -54,6 +61,7 @@ const cons = { ROOM_CREATED: 'ROOM_CREATED', MY_RECEIPT_ARRIVED: 'MY_RECEIPT_ARRIVED', EVENT_ARRIVED: 'EVENT_ARRIVED', + SPACE_SHORTCUT_UPDATED: 'SPACE_SHORTCUT_UPDATED', }, roomTimeline: { EVENT: 'EVENT', diff --git a/src/client/state/navigation.js b/src/client/state/navigation.js index 084af25..5188aad 100644 --- a/src/client/state/navigation.js +++ b/src/client/state/navigation.js @@ -6,19 +6,17 @@ class Navigation extends EventEmitter { constructor() { super(); - this.selectedTab = 'home'; + this.selectedTab = cons.tabs.HOME; this.selectedSpaceId = null; - this.selectedSpacePath = []; + this.selectedSpacePath = [cons.tabs.HOME]; + this.selectedRoomId = null; this.isPeopleDrawerVisible = true; - - // TODO: - window.navigation = this; } _setSpacePath(roomId) { - if (roomId === null) { - this.selectedSpacePath = []; + if (roomId === null || roomId === cons.tabs.HOME) { + this.selectedSpacePath = [cons.tabs.HOME]; return; } if (this.selectedSpacePath.includes(roomId)) { @@ -31,14 +29,24 @@ class Navigation extends EventEmitter { navigate(action) { const actions = { - [cons.actions.navigation.CHANGE_TAB]: () => { + [cons.actions.navigation.SELECT_TAB]: () => { this.selectedTab = action.tabId; - this.emit(cons.events.navigation.TAB_CHANGED, this.selectedTab); + if (this.selectedTab !== cons.tabs.DIRECTS) { + if (this.selectedTab === cons.tabs.HOME) { + this.selectedSpacePath = [cons.tabs.HOME]; + this.selectedSpaceId = null; + } else { + this.selectedSpacePath = [this.selectedTab]; + this.selectedSpaceId = this.selectedTab; + } + this.emit(cons.events.navigation.SPACE_SELECTED, this.selectedSpaceId); + } else this.selectedSpaceId = null; + this.emit(cons.events.navigation.TAB_SELECTED, this.selectedTab); }, [cons.actions.navigation.SELECT_SPACE]: () => { this._setSpacePath(action.roomId); this.selectedSpaceId = action.roomId; - this.emit(cons.events.navigation.SPACE_SELECTED, action.roomId); + this.emit(cons.events.navigation.SPACE_SELECTED, this.selectedSpaceId); }, [cons.actions.navigation.SELECT_ROOM]: () => { const prevSelectedRoomId = this.selectedRoomId;