diff --git a/src/app/hooks/useSelectedSpace.js b/src/app/hooks/useSelectedSpace.js new file mode 100644 index 00000000..535c5dcd --- /dev/null +++ b/src/app/hooks/useSelectedSpace.js @@ -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]; +} diff --git a/src/app/hooks/useSelectedTab.js b/src/app/hooks/useSelectedTab.js new file mode 100644 index 00000000..33b76a81 --- /dev/null +++ b/src/app/hooks/useSelectedTab.js @@ -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]; +} diff --git a/src/app/hooks/useSpaceShortcut.js b/src/app/hooks/useSpaceShortcut.js new file mode 100644 index 00000000..8dca2ba1 --- /dev/null +++ b/src/app/hooks/useSpaceShortcut.js @@ -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]; +} diff --git a/src/app/organisms/navigation/Drawer.jsx b/src/app/organisms/navigation/Drawer.jsx index f31c6b57..e5b9a254 100644 --- a/src/app/organisms/navigation/Drawer.jsx +++ b/src/app/organisms/navigation/Drawer.jsx @@ -14,34 +14,12 @@ import DrawerBreadcrumb from './DrawerBreadcrumb'; import Home from './Home'; import Directs from './Directs'; -function Drawer() { - const [systemState, setSystemState] = useState(null); - const [selectedTab, setSelectedTab] = useState(navigation.selectedTab); - const [spaceId, setSpaceId] = useState(navigation.selectedSpaceId); - const scrollRef = useRef(null); +import { useSelectedTab } from '../../hooks/useSelectedTab'; +import { useSelectedSpace } from '../../hooks/useSelectedSpace'; + +function useSystemState() { + 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(() => { const handleSystemState = (state) => { if (state === 'ERROR' || state === 'RECONNECTING' || state === 'STOPPED') { @@ -55,6 +33,15 @@ function Drawer() { }; }, [systemState]); + return [systemState]; +} + +function Drawer() { + const [systemState] = useSystemState(); + const [selectedTab] = useSelectedTab(); + const [spaceId] = useSelectedSpace(); + const scrollRef = useRef(null); + useEffect(() => { requestAnimationFrame(() => { scrollRef.current.scrollTop = 0; diff --git a/src/app/organisms/navigation/SideBar.jsx b/src/app/organisms/navigation/SideBar.jsx index 8d587e64..8e630d79 100644 --- a/src/app/organisms/navigation/SideBar.jsx +++ b/src/app/organisms/navigation/SideBar.jsx @@ -7,7 +7,6 @@ import colorMXID from '../../../util/colorMXID'; import { selectTab, openInviteList, openSearch, openSettings, } from '../../../client/action/navigation'; -import navigation from '../../../client/state/navigation'; import { abbreviateNumber } from '../../../util/common'; 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 InviteIC from '../../../../public/res/ic/outlined/invite.svg'; +import { useSelectedTab } from '../../hooks/useSelectedTab'; +import { useSpaceShortcut } from '../../hooks/useSpaceShortcut'; + function ProfileAvatarMenu() { const mx = initMatrix.matrixClient; const [profile, setProfile] = useState({ @@ -54,41 +56,42 @@ function ProfileAvatarMenu() { ); } -function SideBar() { - const { roomList, notifications } = initMatrix; - const mx = initMatrix.matrixClient; +function useTotalInvites() { + const { roomList } = initMatrix; const totalInviteCount = () => roomList.inviteRooms.size + roomList.inviteSpaces.size + roomList.inviteDirects.size; - 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(() => { - navigation.on(cons.events.navigation.TAB_SELECTED, onTabSelected); - roomList.on(cons.events.roomList.SPACE_SHORTCUT_UPDATED, onSpaceShortcutUpdated); + const onInviteListChange = () => { + updateTotalInvites(totalInviteCount()); + }; roomList.on(cons.events.roomList.INVITELIST_UPDATED, onInviteListChange); - notifications.on(cons.events.notifications.NOTI_CHANGED, onNotificationChanged); - 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); + }; + }, []); + + 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); }; }, []); @@ -156,7 +159,7 @@ function SideBar() {
{ - [...roomList.spaceShortcut].map((shortcut) => { + spaceShortcut.map((shortcut) => { const sRoomId = shortcut; const room = mx.getRoom(sRoomId); return ( diff --git a/src/client/event/roomList.js b/src/client/event/roomList.js new file mode 100644 index 00000000..0b88e0c9 --- /dev/null +++ b/src/client/event/roomList.js @@ -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 }; diff --git a/src/client/initMatrix.js b/src/client/initMatrix.js index 84e388e1..ce5bf648 100644 --- a/src/client/initMatrix.js +++ b/src/client/initMatrix.js @@ -7,6 +7,7 @@ import RoomList from './state/RoomList'; import RoomsInput from './state/RoomsInput'; import Notifications from './state/Notifications'; import { initHotkeys } from './event/hotkeys'; +import { initRoomListListener } from './event/roomList'; global.Olm = require('@matrix-org/olm'); @@ -64,6 +65,7 @@ class InitMatrix extends EventEmitter { this.roomsInput = new RoomsInput(this.matrixClient); this.notifications = new Notifications(this.roomList); initHotkeys(); + initRoomListListener(this.roomList); this.emit('init_loading_finished'); } },