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

179 lines
6.5 KiB
TypeScript
Raw Normal View History

2021-07-05 06:23:23 -04:00
import {
2021-07-05 06:25:20 -04:00
Home,
UserDetail,
Wrench,
Notepad,
2021-07-05 06:23:23 -04:00
} from "@styled-icons/boxicons-solid";
2021-07-29 10:11:21 -04:00
import { observer } from "mobx-react-lite";
2021-07-05 06:23:23 -04:00
import { Link, Redirect, useLocation, useParams } from "react-router-dom";
2021-07-30 17:40:49 -04:00
import { RelationshipStatus } from "revolt-api/types/Users";
2021-07-05 06:23:23 -04:00
import { Text } from "preact-i18n";
import { useContext, useEffect } from "preact/hooks";
2021-06-19 10:29:04 -04:00
2021-07-05 06:23:23 -04:00
import ConditionalLink from "../../../lib/ConditionalLink";
2021-06-20 15:30:42 -04:00
import PaintCounter from "../../../lib/PaintCounter";
2021-07-05 06:23:23 -04:00
import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
import { dispatch } from "../../../redux";
2021-06-20 15:30:42 -04:00
import { connectState } from "../../../redux/connector";
2021-06-19 10:29:04 -04:00
import { Unreads } from "../../../redux/reducers/unreads";
2021-07-05 06:23:23 -04:00
2021-06-19 15:24:11 -04:00
import { useIntermediate } from "../../../context/intermediate/Intermediate";
2021-07-05 06:23:23 -04:00
import { AppContext } from "../../../context/revoltjs/RevoltClient";
2021-06-19 10:29:04 -04:00
2021-07-05 06:23:23 -04:00
import Category from "../../ui/Category";
import placeholderSVG from "../items/placeholder.svg";
2021-07-05 06:23:23 -04:00
import { mapChannelWithUnread, useUnreads } from "./common";
import { GenericSidebarBase, GenericSidebarList } from "../SidebarBase";
import ButtonItem, { ChannelButton } from "../items/ButtonItem";
import ConnectionStatus from "../items/ConnectionStatus";
type Props = {
2021-07-05 06:25:20 -04:00
unreads: Unreads;
2021-07-05 06:23:23 -04:00
};
2021-06-19 10:29:04 -04:00
2021-07-29 10:11:21 -04:00
const HomeSidebar = observer((props: Props) => {
2021-07-05 06:25:20 -04:00
const { pathname } = useLocation();
const client = useContext(AppContext);
const { channel } = useParams<{ channel: string }>();
const { openScreen } = useIntermediate();
2021-07-30 17:40:49 -04:00
const channels = [...client.channels.values()]
2021-07-29 13:41:01 -04:00
.filter(
(x) =>
x.channel_type === "DirectMessage" ||
x.channel_type === "Group",
)
.map((x) => mapChannelWithUnread(x, props.unreads));
2021-07-05 06:25:20 -04:00
2021-07-30 17:40:49 -04:00
const obj = client.channels.get(channel);
2021-07-05 06:25:20 -04:00
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-07-29 13:41:01 -04:00
channels.sort((b, a) => a.timestamp.localeCompare(b.timestamp));
2021-07-05 06:25:20 -04:00
return (
2021-08-08 11:17:16 -04:00
<GenericSidebarBase mobilePadding>
2021-07-05 06:25:20 -04:00
<ConnectionStatus />
<GenericSidebarList>
<ConditionalLink active={pathname === "/"} to="/">
<ButtonItem active={pathname === "/"}>
<Home size={20} />
<span>
<Text id="app.navigation.tabs.home" />
</span>
</ButtonItem>
</ConditionalLink>
2021-07-05 06:25:20 -04:00
{!isTouchscreenDevice && (
<>
<ConditionalLink
active={pathname === "/friends"}
to="/friends">
<ButtonItem
active={pathname === "/friends"}
alert={
2021-07-30 17:40:49 -04:00
typeof [...client.users.values()].find(
2021-07-05 06:25:20 -04:00
(user) =>
user?.relationship ===
2021-07-30 17:40:49 -04:00
RelationshipStatus.Incoming,
2021-07-05 06:25:20 -04:00
) !== "undefined"
? "unread"
: undefined
}>
<UserDetail size={20} />
<span>
<Text id="app.navigation.tabs.friends" />
</span>
</ButtonItem>
</ConditionalLink>
</>
)}
<ConditionalLink
active={obj?.channel_type === "SavedMessages"}
to="/open/saved">
<ButtonItem active={obj?.channel_type === "SavedMessages"}>
<Notepad size={20} />
<span>
<Text id="app.navigation.tabs.saved" />
</span>
</ButtonItem>
</ConditionalLink>
{import.meta.env.DEV && (
<Link to="/dev">
<ButtonItem active={pathname === "/dev"}>
<Wrench size={20} />
<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",
})
}
/>
2021-07-29 13:41:01 -04:00
{channels.length === 0 && (
<img src={placeholderSVG} loading="eager" />
)}
2021-07-29 13:41:01 -04:00
{channels.map((x) => {
2021-07-05 06:25:20 -04:00
let user;
2021-07-29 13:41:01 -04:00
if (x.channel.channel_type === "DirectMessage") {
if (!x.channel.active) return null;
2021-07-30 17:40:49 -04:00
user = x.channel.recipient;
2021-07-05 06:25:20 -04:00
if (!user) {
console.warn(
2021-07-29 13:41:01 -04:00
`Skipped DM ${x.channel._id} because user was missing.`,
2021-07-05 06:25:20 -04:00
);
return null;
}
}
return (
<ConditionalLink
2021-08-05 09:47:00 -04:00
key={x.channel._id}
2021-07-29 13:41:01 -04:00
active={x.channel._id === channel}
to={`/channel/${x.channel._id}`}>
2021-07-05 06:25:20 -04:00
<ChannelButton
user={user}
2021-07-29 13:41:01 -04:00
channel={x.channel}
2021-07-05 06:25:20 -04:00
alert={x.unread}
alertCount={x.alertCount}
2021-07-29 13:41:01 -04:00
active={x.channel._id === channel}
2021-07-05 06:25:20 -04:00
/>
</ConditionalLink>
);
})}
<PaintCounter />
</GenericSidebarList>
</GenericSidebarBase>
);
2021-07-29 10:11:21 -04:00
});
2021-06-19 10:29:04 -04:00
export default connectState(
2021-07-05 06:25:20 -04:00
HomeSidebar,
(state) => {
return {
unreads: state.unreads,
};
},
true,
2021-06-19 10:29:04 -04:00
);