2021-09-12 17:14:13 +02:00
|
|
|
import React, { useState, useEffect, useRef } from 'react';
|
2021-09-05 15:26:34 +02:00
|
|
|
import PropTypes from 'prop-types';
|
2021-09-03 14:28:01 +02:00
|
|
|
import './DrawerBreadcrumb.scss';
|
|
|
|
|
2021-11-23 07:26:02 +01:00
|
|
|
import { twemojify } from '../../../util/twemojify';
|
|
|
|
|
2021-09-03 14:28:01 +02:00
|
|
|
import initMatrix from '../../../client/initMatrix';
|
|
|
|
import cons from '../../../client/state/cons';
|
|
|
|
import { selectSpace } from '../../../client/action/navigation';
|
|
|
|
import navigation from '../../../client/state/navigation';
|
2021-09-12 17:14:13 +02:00
|
|
|
import { abbreviateNumber } from '../../../util/common';
|
2021-09-03 14:28:01 +02:00
|
|
|
|
|
|
|
import Text from '../../atoms/text/Text';
|
|
|
|
import RawIcon from '../../atoms/system-icons/RawIcon';
|
|
|
|
import Button from '../../atoms/button/Button';
|
|
|
|
import ScrollView from '../../atoms/scroll/ScrollView';
|
2021-09-12 17:14:13 +02:00
|
|
|
import NotificationBadge from '../../atoms/badge/NotificationBadge';
|
2021-09-03 14:28:01 +02:00
|
|
|
|
|
|
|
import ChevronRightIC from '../../../../public/res/ic/outlined/chevron-right.svg';
|
|
|
|
|
2021-09-05 15:26:34 +02:00
|
|
|
function DrawerBreadcrumb({ spaceId }) {
|
2021-09-12 17:14:13 +02:00
|
|
|
const [, forceUpdate] = useState({});
|
2021-09-03 14:28:01 +02:00
|
|
|
const scrollRef = useRef(null);
|
2021-09-12 17:14:13 +02:00
|
|
|
const { roomList, notifications } = initMatrix;
|
2021-09-03 14:28:01 +02:00
|
|
|
const mx = initMatrix.matrixClient;
|
|
|
|
const spacePath = navigation.selectedSpacePath;
|
|
|
|
|
2021-09-12 17:14:13 +02:00
|
|
|
function onNotiChanged(roomId, total, prevTotal) {
|
|
|
|
if (total === prevTotal) return;
|
|
|
|
if (navigation.selectedSpacePath.includes(roomId)) {
|
|
|
|
forceUpdate({});
|
|
|
|
}
|
|
|
|
if (navigation.selectedSpacePath[0] === cons.tabs.HOME) {
|
|
|
|
if (!roomList.isOrphan(roomId)) return;
|
|
|
|
if (roomList.directs.has(roomId)) return;
|
|
|
|
forceUpdate({});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-05 15:26:34 +02:00
|
|
|
useEffect(() => {
|
2021-09-03 14:28:01 +02:00
|
|
|
requestAnimationFrame(() => {
|
|
|
|
if (scrollRef?.current === null) return;
|
|
|
|
scrollRef.current.scrollLeft = scrollRef.current.scrollWidth;
|
|
|
|
});
|
2021-09-12 17:14:13 +02:00
|
|
|
notifications.on(cons.events.notifications.NOTI_CHANGED, onNotiChanged);
|
|
|
|
return () => {
|
|
|
|
notifications.removeListener(cons.events.notifications.NOTI_CHANGED, onNotiChanged);
|
|
|
|
};
|
2021-09-05 15:26:34 +02:00
|
|
|
}, [spaceId]);
|
2021-09-03 14:28:01 +02:00
|
|
|
|
2021-09-12 17:14:13 +02:00
|
|
|
function getHomeNotiExcept(childId) {
|
|
|
|
const orphans = roomList.getOrphans();
|
|
|
|
const childIndex = orphans.indexOf(childId);
|
|
|
|
if (childId !== -1) orphans.splice(childIndex, 1);
|
|
|
|
|
|
|
|
let noti = null;
|
|
|
|
|
|
|
|
orphans.forEach((roomId) => {
|
|
|
|
if (!notifications.hasNoti(roomId)) return;
|
|
|
|
if (noti === null) noti = { total: 0, highlight: 0 };
|
|
|
|
const childNoti = notifications.getNoti(roomId);
|
|
|
|
noti.total += childNoti.total;
|
|
|
|
noti.highlight += childNoti.highlight;
|
|
|
|
});
|
|
|
|
|
|
|
|
return noti;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getNotiExcept(roomId, childId) {
|
|
|
|
if (!notifications.hasNoti(roomId)) return null;
|
|
|
|
|
|
|
|
const noti = notifications.getNoti(roomId);
|
|
|
|
if (!notifications.hasNoti(childId)) return noti;
|
|
|
|
if (noti.from === null) return noti;
|
|
|
|
|
|
|
|
const childNoti = notifications.getNoti(childId);
|
|
|
|
|
2022-03-13 10:42:54 +01:00
|
|
|
let noOther = true;
|
|
|
|
let total = 0;
|
|
|
|
let highlight = 0;
|
|
|
|
noti.from.forEach((fromId) => {
|
|
|
|
if (childNoti.from.has(fromId)) return;
|
|
|
|
noOther = false;
|
|
|
|
const fromNoti = notifications.getNoti(fromId);
|
|
|
|
total += fromNoti.total;
|
|
|
|
highlight += fromNoti.highlight;
|
|
|
|
});
|
|
|
|
|
|
|
|
if (noOther) return null;
|
|
|
|
return { total, highlight };
|
2021-09-12 17:14:13 +02:00
|
|
|
}
|
|
|
|
|
2021-09-03 14:28:01 +02:00
|
|
|
return (
|
2022-02-16 15:26:02 +01:00
|
|
|
<div className="drawer-breadcrumb__wrapper">
|
2021-09-03 14:28:01 +02:00
|
|
|
<ScrollView ref={scrollRef} horizontal vertical={false} invisible>
|
2022-02-16 15:26:02 +01:00
|
|
|
<div className="drawer-breadcrumb">
|
2021-09-03 14:28:01 +02:00
|
|
|
{
|
2021-09-05 15:26:34 +02:00
|
|
|
spacePath.map((id, index) => {
|
2021-09-12 17:14:13 +02:00
|
|
|
const noti = (id !== cons.tabs.HOME && index < spacePath.length)
|
|
|
|
? getNotiExcept(id, (index === spacePath.length - 1) ? null : spacePath[index + 1])
|
|
|
|
: getHomeNotiExcept((index === spacePath.length - 1) ? null : spacePath[index + 1]);
|
|
|
|
|
2021-09-05 15:26:34 +02:00
|
|
|
return (
|
|
|
|
<React.Fragment
|
|
|
|
key={id}
|
2021-09-03 14:28:01 +02:00
|
|
|
>
|
2021-09-12 17:14:13 +02:00
|
|
|
{ index !== 0 && <RawIcon size="extra-small" src={ChevronRightIC} />}
|
2021-09-05 15:26:34 +02:00
|
|
|
<Button
|
2022-02-16 15:26:02 +01:00
|
|
|
className={index === spacePath.length - 1 ? 'drawer-breadcrumb__btn--selected' : ''}
|
2021-09-05 15:26:34 +02:00
|
|
|
onClick={() => selectSpace(id)}
|
|
|
|
>
|
2021-11-23 07:26:02 +01:00
|
|
|
<Text variant="b2">{id === cons.tabs.HOME ? 'Home' : twemojify(mx.getRoom(id).name)}</Text>
|
2021-09-12 17:14:13 +02:00
|
|
|
{ noti !== null && (
|
|
|
|
<NotificationBadge
|
|
|
|
alert={noti.highlight !== 0}
|
|
|
|
content={noti.total > 0 ? abbreviateNumber(noti.total) : null}
|
|
|
|
/>
|
|
|
|
)}
|
2021-09-05 15:26:34 +02:00
|
|
|
</Button>
|
|
|
|
</React.Fragment>
|
|
|
|
);
|
|
|
|
})
|
2021-09-03 14:28:01 +02:00
|
|
|
}
|
|
|
|
<div style={{ width: 'var(--sp-extra-tight)', height: '100%' }} />
|
|
|
|
</div>
|
|
|
|
</ScrollView>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-09-05 15:26:34 +02:00
|
|
|
DrawerBreadcrumb.defaultProps = {
|
|
|
|
spaceId: null,
|
|
|
|
};
|
|
|
|
|
|
|
|
DrawerBreadcrumb.propTypes = {
|
|
|
|
spaceId: PropTypes.string,
|
|
|
|
};
|
|
|
|
|
2021-09-03 14:28:01 +02:00
|
|
|
export default DrawerBreadcrumb;
|