Refactor navigation
Signed-off-by: Ajay Bura <ajbura@gmail.com>
This commit is contained in:
parent
f47998a553
commit
992da7c7be
7 changed files with 130 additions and 55 deletions
21
src/app/hooks/useSelectedSpace.js
Normal file
21
src/app/hooks/useSelectedSpace.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/* eslint-disable import/prefer-default-export */
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
import cons from '../../client/state/cons';
|
||||||
|
import navigation from '../../client/state/navigation';
|
||||||
|
|
||||||
|
export function useSelectedSpace() {
|
||||||
|
const [spaceId, setSpaceId] = useState(navigation.selectedSpaceId);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const onSpaceSelected = (roomId) => {
|
||||||
|
setSpaceId(roomId);
|
||||||
|
};
|
||||||
|
navigation.on(cons.events.navigation.SPACE_SELECTED, onSpaceSelected);
|
||||||
|
return () => {
|
||||||
|
navigation.removeListener(cons.events.navigation.SPACE_SELECTED, onSpaceSelected);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return [spaceId];
|
||||||
|
}
|
21
src/app/hooks/useSelectedTab.js
Normal file
21
src/app/hooks/useSelectedTab.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/* eslint-disable import/prefer-default-export */
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
import cons from '../../client/state/cons';
|
||||||
|
import navigation from '../../client/state/navigation';
|
||||||
|
|
||||||
|
export function useSelectedTab() {
|
||||||
|
const [selectedTab, setSelectedTab] = useState(navigation.selectedTab);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const onTabSelected = (tabId) => {
|
||||||
|
setSelectedTab(tabId);
|
||||||
|
};
|
||||||
|
navigation.on(cons.events.navigation.TAB_SELECTED, onTabSelected);
|
||||||
|
return () => {
|
||||||
|
navigation.removeListener(cons.events.navigation.TAB_SELECTED, onTabSelected);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return [selectedTab];
|
||||||
|
}
|
22
src/app/hooks/useSpaceShortcut.js
Normal file
22
src/app/hooks/useSpaceShortcut.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/* eslint-disable import/prefer-default-export */
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
import initMatrix from '../../client/initMatrix';
|
||||||
|
import cons from '../../client/state/cons';
|
||||||
|
|
||||||
|
export function useSpaceShortcut() {
|
||||||
|
const { roomList } = initMatrix;
|
||||||
|
const [spaceShortcut, setSpaceShortcut] = useState([...roomList.spaceShortcut]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const onSpaceShortcutUpdated = () => {
|
||||||
|
setSpaceShortcut([...roomList.spaceShortcut]);
|
||||||
|
};
|
||||||
|
roomList.on(cons.events.roomList.SPACE_SHORTCUT_UPDATED, onSpaceShortcutUpdated);
|
||||||
|
return () => {
|
||||||
|
roomList.removeListener(cons.events.roomList.SPACE_SHORTCUT_UPDATED, onSpaceShortcutUpdated);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return [spaceShortcut];
|
||||||
|
}
|
|
@ -14,34 +14,12 @@ import DrawerBreadcrumb from './DrawerBreadcrumb';
|
||||||
import Home from './Home';
|
import Home from './Home';
|
||||||
import Directs from './Directs';
|
import Directs from './Directs';
|
||||||
|
|
||||||
function Drawer() {
|
import { useSelectedTab } from '../../hooks/useSelectedTab';
|
||||||
const [systemState, setSystemState] = useState(null);
|
import { useSelectedSpace } from '../../hooks/useSelectedSpace';
|
||||||
const [selectedTab, setSelectedTab] = useState(navigation.selectedTab);
|
|
||||||
const [spaceId, setSpaceId] = useState(navigation.selectedSpaceId);
|
function useSystemState() {
|
||||||
const scrollRef = useRef(null);
|
const [systemState, setSystemState] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const onTabSelected = (tabId) => {
|
|
||||||
setSelectedTab(tabId);
|
|
||||||
};
|
|
||||||
const onSpaceSelected = (roomId) => {
|
|
||||||
setSpaceId(roomId);
|
|
||||||
};
|
|
||||||
const 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]);
|
|
||||||
};
|
|
||||||
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_SELECTED, onTabSelected);
|
|
||||||
navigation.removeListener(cons.events.navigation.SPACE_SELECTED, onSpaceSelected);
|
|
||||||
initMatrix.roomList.removeListener(cons.events.roomList.ROOM_LEAVED, onRoomLeaved);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleSystemState = (state) => {
|
const handleSystemState = (state) => {
|
||||||
if (state === 'ERROR' || state === 'RECONNECTING' || state === 'STOPPED') {
|
if (state === 'ERROR' || state === 'RECONNECTING' || state === 'STOPPED') {
|
||||||
|
@ -55,6 +33,15 @@ function Drawer() {
|
||||||
};
|
};
|
||||||
}, [systemState]);
|
}, [systemState]);
|
||||||
|
|
||||||
|
return [systemState];
|
||||||
|
}
|
||||||
|
|
||||||
|
function Drawer() {
|
||||||
|
const [systemState] = useSystemState();
|
||||||
|
const [selectedTab] = useSelectedTab();
|
||||||
|
const [spaceId] = useSelectedSpace();
|
||||||
|
const scrollRef = useRef(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
scrollRef.current.scrollTop = 0;
|
scrollRef.current.scrollTop = 0;
|
||||||
|
|
|
@ -7,7 +7,6 @@ import colorMXID from '../../../util/colorMXID';
|
||||||
import {
|
import {
|
||||||
selectTab, openInviteList, openSearch, openSettings,
|
selectTab, openInviteList, openSearch, openSettings,
|
||||||
} from '../../../client/action/navigation';
|
} from '../../../client/action/navigation';
|
||||||
import navigation from '../../../client/state/navigation';
|
|
||||||
import { abbreviateNumber } from '../../../util/common';
|
import { abbreviateNumber } from '../../../util/common';
|
||||||
|
|
||||||
import ScrollView from '../../atoms/scroll/ScrollView';
|
import ScrollView from '../../atoms/scroll/ScrollView';
|
||||||
|
@ -18,6 +17,9 @@ import UserIC from '../../../../public/res/ic/outlined/user.svg';
|
||||||
import SearchIC from '../../../../public/res/ic/outlined/search.svg';
|
import SearchIC from '../../../../public/res/ic/outlined/search.svg';
|
||||||
import InviteIC from '../../../../public/res/ic/outlined/invite.svg';
|
import InviteIC from '../../../../public/res/ic/outlined/invite.svg';
|
||||||
|
|
||||||
|
import { useSelectedTab } from '../../hooks/useSelectedTab';
|
||||||
|
import { useSpaceShortcut } from '../../hooks/useSpaceShortcut';
|
||||||
|
|
||||||
function ProfileAvatarMenu() {
|
function ProfileAvatarMenu() {
|
||||||
const mx = initMatrix.matrixClient;
|
const mx = initMatrix.matrixClient;
|
||||||
const [profile, setProfile] = useState({
|
const [profile, setProfile] = useState({
|
||||||
|
@ -54,41 +56,42 @@ function ProfileAvatarMenu() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function SideBar() {
|
function useTotalInvites() {
|
||||||
const { roomList, notifications } = initMatrix;
|
const { roomList } = initMatrix;
|
||||||
const mx = initMatrix.matrixClient;
|
|
||||||
const totalInviteCount = () => roomList.inviteRooms.size
|
const totalInviteCount = () => roomList.inviteRooms.size
|
||||||
+ roomList.inviteSpaces.size
|
+ roomList.inviteSpaces.size
|
||||||
+ roomList.inviteDirects.size;
|
+ roomList.inviteDirects.size;
|
||||||
|
|
||||||
const [totalInvites, updateTotalInvites] = useState(totalInviteCount());
|
const [totalInvites, updateTotalInvites] = useState(totalInviteCount());
|
||||||
const [selectedTab, setSelectedTab] = useState(navigation.selectedTab);
|
|
||||||
const [, forceUpdate] = useState({});
|
|
||||||
|
|
||||||
function onTabSelected(tabId) {
|
|
||||||
setSelectedTab(tabId);
|
|
||||||
}
|
|
||||||
function onInviteListChange() {
|
|
||||||
updateTotalInvites(totalInviteCount());
|
|
||||||
}
|
|
||||||
function onSpaceShortcutUpdated() {
|
|
||||||
forceUpdate({});
|
|
||||||
}
|
|
||||||
function onNotificationChanged(roomId, total, prevTotal) {
|
|
||||||
if (total === prevTotal) return;
|
|
||||||
forceUpdate({});
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
navigation.on(cons.events.navigation.TAB_SELECTED, onTabSelected);
|
const onInviteListChange = () => {
|
||||||
roomList.on(cons.events.roomList.SPACE_SHORTCUT_UPDATED, onSpaceShortcutUpdated);
|
updateTotalInvites(totalInviteCount());
|
||||||
|
};
|
||||||
roomList.on(cons.events.roomList.INVITELIST_UPDATED, onInviteListChange);
|
roomList.on(cons.events.roomList.INVITELIST_UPDATED, onInviteListChange);
|
||||||
notifications.on(cons.events.notifications.NOTI_CHANGED, onNotificationChanged);
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
navigation.removeListener(cons.events.navigation.TAB_SELECTED, onTabSelected);
|
|
||||||
roomList.removeListener(cons.events.roomList.SPACE_SHORTCUT_UPDATED, onSpaceShortcutUpdated);
|
|
||||||
roomList.removeListener(cons.events.roomList.INVITELIST_UPDATED, onInviteListChange);
|
roomList.removeListener(cons.events.roomList.INVITELIST_UPDATED, onInviteListChange);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return [totalInvites];
|
||||||
|
}
|
||||||
|
|
||||||
|
function SideBar() {
|
||||||
|
const { roomList, notifications } = initMatrix;
|
||||||
|
const mx = initMatrix.matrixClient;
|
||||||
|
|
||||||
|
const [selectedTab] = useSelectedTab();
|
||||||
|
const [spaceShortcut] = useSpaceShortcut();
|
||||||
|
const [totalInvites] = useTotalInvites();
|
||||||
|
const [, forceUpdate] = useState({});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function onNotificationChanged(roomId, total, prevTotal) {
|
||||||
|
if (total === prevTotal) return;
|
||||||
|
forceUpdate({});
|
||||||
|
}
|
||||||
|
notifications.on(cons.events.notifications.NOTI_CHANGED, onNotificationChanged);
|
||||||
|
return () => {
|
||||||
notifications.removeListener(cons.events.notifications.NOTI_CHANGED, onNotificationChanged);
|
notifications.removeListener(cons.events.notifications.NOTI_CHANGED, onNotificationChanged);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
@ -156,7 +159,7 @@ function SideBar() {
|
||||||
<div className="sidebar-divider" />
|
<div className="sidebar-divider" />
|
||||||
<div className="space-container">
|
<div className="space-container">
|
||||||
{
|
{
|
||||||
[...roomList.spaceShortcut].map((shortcut) => {
|
spaceShortcut.map((shortcut) => {
|
||||||
const sRoomId = shortcut;
|
const sRoomId = shortcut;
|
||||||
const room = mx.getRoom(sRoomId);
|
const room = mx.getRoom(sRoomId);
|
||||||
return (
|
return (
|
||||||
|
|
19
src/client/event/roomList.js
Normal file
19
src/client/event/roomList.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import cons from '../state/cons';
|
||||||
|
import navigation from '../state/navigation';
|
||||||
|
import { selectTab, selectSpace } from '../action/navigation';
|
||||||
|
|
||||||
|
const listenRoomLeave = (roomId) => {
|
||||||
|
const lRoomIndex = navigation.selectedSpacePath.indexOf(roomId);
|
||||||
|
if (lRoomIndex === -1) return;
|
||||||
|
if (lRoomIndex === 0) selectTab(cons.tabs.HOME);
|
||||||
|
else selectSpace(navigation.selectedSpacePath[lRoomIndex - 1]);
|
||||||
|
};
|
||||||
|
|
||||||
|
function initRoomListListener(roomList) {
|
||||||
|
roomList.on(cons.events.roomList.ROOM_LEAVED, listenRoomLeave);
|
||||||
|
}
|
||||||
|
function removeRoomListListener(roomList) {
|
||||||
|
roomList.removeListener(cons.events.roomList.ROOM_LEAVED, listenRoomLeave);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { initRoomListListener, removeRoomListListener };
|
|
@ -7,6 +7,7 @@ import RoomList from './state/RoomList';
|
||||||
import RoomsInput from './state/RoomsInput';
|
import RoomsInput from './state/RoomsInput';
|
||||||
import Notifications from './state/Notifications';
|
import Notifications from './state/Notifications';
|
||||||
import { initHotkeys } from './event/hotkeys';
|
import { initHotkeys } from './event/hotkeys';
|
||||||
|
import { initRoomListListener } from './event/roomList';
|
||||||
|
|
||||||
global.Olm = require('@matrix-org/olm');
|
global.Olm = require('@matrix-org/olm');
|
||||||
|
|
||||||
|
@ -64,6 +65,7 @@ class InitMatrix extends EventEmitter {
|
||||||
this.roomsInput = new RoomsInput(this.matrixClient);
|
this.roomsInput = new RoomsInput(this.matrixClient);
|
||||||
this.notifications = new Notifications(this.roomList);
|
this.notifications = new Notifications(this.roomList);
|
||||||
initHotkeys();
|
initHotkeys();
|
||||||
|
initRoomListListener(this.roomList);
|
||||||
this.emit('init_loading_finished');
|
this.emit('init_loading_finished');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue