revite/src/components/navigation/left/HomeSidebar.tsx

153 lines
6.2 KiB
TypeScript
Raw Normal View History

import { Text } from "preact-i18n";
import { useContext, useEffect } from "preact/hooks";
import { Home, UserDetail, Wrench, Notepad } from "@styled-icons/boxicons-solid";
2021-06-19 10:29:04 -04:00
2021-06-20 15:30:42 -04:00
import Category from '../../ui/Category';
import { dispatch } from "../../../redux";
2021-06-20 15:30:42 -04:00
import PaintCounter from "../../../lib/PaintCounter";
import UserHeader from "../../common/user/UserHeader";
import { Channels } from "revolt.js/dist/api/objects";
import { connectState } from "../../../redux/connector";
import ConnectionStatus from '../items/ConnectionStatus';
2021-06-19 10:29:04 -04:00
import { Unreads } from "../../../redux/reducers/unreads";
import ConditionalLink from "../../../lib/ConditionalLink";
2021-06-19 10:29:04 -04:00
import { mapChannelWithUnread, useUnreads } from "./common";
2021-06-20 15:30:42 -04:00
import { Users as UsersNS } from 'revolt.js/dist/api/objects';
2021-06-19 10:29:04 -04:00
import ButtonItem, { ChannelButton } from '../items/ButtonItem';
2021-06-20 15:30:42 -04:00
import { AppContext } from "../../../context/revoltjs/RevoltClient";
import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
import { GenericSidebarBase, GenericSidebarList } from "../SidebarBase";
2021-06-20 15:30:42 -04:00
import { Link, Redirect, useLocation, useParams } from "react-router-dom";
2021-06-19 15:24:11 -04:00
import { useIntermediate } from "../../../context/intermediate/Intermediate";
2021-06-20 15:30:42 -04:00
import { useDMs, useForceUpdate, useUsers } from "../../../context/revoltjs/hooks";
2021-06-19 10:29:04 -04:00
import placeholderSVG from "../items/placeholder.svg";
type Props = {
2021-06-19 10:29:04 -04:00
unreads: Unreads;
}
function HomeSidebar(props: Props) {
const { pathname } = useLocation();
2021-06-19 13:46:05 -04:00
const client = useContext(AppContext);
2021-06-19 10:29:04 -04:00
const { channel } = useParams<{ channel: string }>();
2021-06-19 18:12:27 -04:00
const { openScreen } = useIntermediate();
2021-06-19 10:29:04 -04:00
const ctx = useForceUpdate();
2021-06-19 18:12:27 -04:00
const channels = useDMs(ctx);
2021-06-19 10:29:04 -04:00
const obj = channels.find(x => x?._id === channel);
if (channel && !obj) return <Redirect to="/" />;
if (obj) useUnreads({ ...props, channel: obj });
useEffect(() => {
if (!channel) return;
dispatch({
type: 'LAST_OPENED_SET',
parent: 'home',
child: channel
});
}, [ channel ]);
2021-06-19 18:12:27 -04:00
const channelsArr = channels
.filter(x => x.channel_type !== 'SavedMessages')
2021-06-19 10:29:04 -04:00
.map(x => mapChannelWithUnread(x, props.unreads));
2021-06-19 18:12:27 -04:00
const users = useUsers(
(channelsArr as (Channels.DirectMessageChannel | Channels.GroupChannel)[])
.reduce((prev: any, cur) => [ ...prev, ...cur.recipients ], [])
, ctx);
2021-06-19 10:29:04 -04:00
channelsArr.sort((b, a) => a.timestamp.localeCompare(b.timestamp));
return (
<GenericSidebarBase padding>
2021-06-19 10:29:04 -04:00
<UserHeader user={client.user!} />
<ConnectionStatus />
<GenericSidebarList>
2021-06-19 10:29:04 -04:00
{!isTouchscreenDevice && (
<>
<ConditionalLink active={pathname === "/"} to="/">
2021-06-19 10:29:04 -04:00
<ButtonItem active={pathname === "/"}>
<Home size={20} />
<span><Text id="app.navigation.tabs.home" /></span>
</ButtonItem>
</ConditionalLink>
<ConditionalLink active={pathname === "/friends"} to="/friends">
2021-06-19 10:29:04 -04:00
<ButtonItem
active={pathname === "/friends"}
alert={
typeof users.find(
user =>
user?.relationship ===
UsersNS.Relationship.Incoming
) !== "undefined" ? 'unread' : undefined
}
>
<UserDetail size={20} />
2021-06-19 10:29:04 -04:00
<span><Text id="app.navigation.tabs.friends" /></span>
</ButtonItem>
</ConditionalLink>
2021-06-19 10:29:04 -04:00
</>
)}
<ConditionalLink active={obj?.channel_type === "SavedMessages"} to="/open/saved">
2021-06-19 10:29:04 -04:00
<ButtonItem active={obj?.channel_type === "SavedMessages"}>
<Notepad size={20} />
2021-06-19 10:29:04 -04:00
<span><Text id="app.navigation.tabs.saved" /></span>
</ButtonItem>
</ConditionalLink>
2021-06-19 10:29:04 -04:00
{import.meta.env.DEV && (
<Link to="/dev">
<ButtonItem active={pathname === "/dev"}>
2021-06-27 06:17:59 -04:00
<Wrench size={20} />
2021-06-19 10:29:04 -04:00
<span><Text id="app.navigation.tabs.dev" /></span>
</ButtonItem>
</Link>
)}
<Category
text={<Text id="app.main.categories.conversations" />}
action={() => openScreen({ id: "special_input", type: "create_group" })} />
{channelsArr.length === 0 && <img src={placeholderSVG} />}
2021-06-19 10:29:04 -04:00
{channelsArr.map(x => {
let user;
if (x.channel_type === 'DirectMessage') {
if (!x.active) return null;
2021-06-19 10:29:04 -04:00
let recipient = client.channels.getRecipient(x._id);
2021-06-20 15:30:42 -04:00
user = users.find(x => x?._id === recipient);
2021-06-20 15:30:42 -04:00
if (!user) {
console.warn(`Skipped DM ${x._id} because user was missing.`);
return null;
}
2021-06-19 10:29:04 -04:00
}
return (
<ConditionalLink active={x._id === channel} to={`/channel/${x._id}`}>
2021-06-19 10:29:04 -04:00
<ChannelButton
user={user}
channel={x}
alert={x.unread}
alertCount={x.alertCount}
active={x._id === channel}
/>
</ConditionalLink>
2021-06-19 10:29:04 -04:00
);
})}
<PaintCounter />
</GenericSidebarList>
</GenericSidebarBase>
2021-06-19 10:29:04 -04:00
);
};
export default connectState(
HomeSidebar,
state => {
return {
unreads: state.unreads
};
},
true
);