import { Plus } from "@styled-icons/boxicons-regular"; import { useLocation, useParams } from "react-router-dom"; import { Channel, Servers } from "revolt.js/dist/api/objects"; import styled, { css } from "styled-components"; import { attachContextMenu, openContextMenu } from "preact-context-menu"; import ConditionalLink from "../../../lib/ConditionalLink"; import PaintCounter from "../../../lib/PaintCounter"; import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice"; import { connectState } from "../../../redux/connector"; import { LastOpened } from "../../../redux/reducers/last_opened"; import { Unreads } from "../../../redux/reducers/unreads"; import { useIntermediate } from "../../../context/intermediate/Intermediate"; import { useChannels, useForceUpdate, useSelf, useServers, } from "../../../context/revoltjs/hooks"; import ServerIcon from "../../common/ServerIcon"; import Tooltip from "../../common/Tooltip"; import UserIcon from "../../common/user/UserIcon"; import IconButton from "../../ui/IconButton"; import LineDivider from "../../ui/LineDivider"; import { mapChannelWithUnread } from "./common"; import { Children } from "../../../types/Preact"; import UserHover from "../../common/user/UserHover"; function Icon({ children, unread, size, }: { children: Children; unread?: "mention" | "unread"; size: number; }) { return ( ); } const ServersBase = styled.div` width: 56px; height: 100%; display: flex; flex-direction: column; ${isTouchscreenDevice && css` padding-bottom: 50px; `} `; const ServerList = styled.div` flex-grow: 1; display: flex; overflow-y: scroll; padding-bottom: 48px; flex-direction: column; // border-right: 2px solid var(--accent); scrollbar-width: none; > :first-child > svg { margin: 6px 0 6px 4px; } &::-webkit-scrollbar { width: 0px; } `; const ServerEntry = styled.div<{ active: boolean; home?: boolean }>` height: 58px; display: flex; align-items: center; justify-content: flex-end; > * { // outline: 1px solid red; } > div { width: 46px; height: 46px; display: grid; place-items: center; border-start-start-radius: 50%; border-end-start-radius: 50%; &:active { transform: translateY(1px); } ${(props) => props.active && css` background: var(--sidebar-active); &:active { transform: none; } `} } span { width: 6px; height: 46px; ${(props) => props.active && css` background-color: var(--sidebar-active); &::before, &::after { // outline: 1px solid blue; } &::before, &::after { content: ""; display: block; position: relative; width: 31px; height: 72px; margin-top: -72px; margin-left: -25px; z-index: -1; background-color: var(--background); border-bottom-right-radius: 32px; box-shadow: 0 32px 0 0 var(--sidebar-active); } &::after { transform: scaleY(-1) translateY(-118px); } `} } ${(props) => (!props.active || props.home) && css` cursor: pointer; `} `; interface Props { unreads: Unreads; lastOpened: LastOpened; } export function ServerListSidebar({ unreads, lastOpened }: Props) { const ctx = useForceUpdate(); const self = useSelf(ctx); const activeServers = useServers(undefined, ctx) as Servers.Server[]; const channels = (useChannels(undefined, ctx) as Channel[]).map((x) => mapChannelWithUnread(x, unreads), ); const unreadChannels = channels.filter((x) => x.unread).map((x) => x._id); const servers = activeServers.map((server) => { let alertCount = 0; for (let id of server.channels) { let channel = channels.find((x) => x._id === id); if (channel?.alertCount) { alertCount += channel.alertCount; } } return { ...server, unread: (typeof server.channels.find((x) => unreadChannels.includes(x), ) !== "undefined" ? alertCount > 0 ? "mention" : "unread" : undefined) as "mention" | "unread" | undefined, alertCount, }; }); const path = useLocation().pathname; const { server: server_id } = useParams<{ server?: string }>(); const server = servers.find((x) => x!._id == server_id); const { openScreen } = useIntermediate(); let homeUnread: "mention" | "unread" | undefined; let alertCount = 0; for (let x of channels) { if ( ((x.channel_type === "DirectMessage" && x.active) || x.channel_type === "Group") && x.unread ) { homeUnread = "unread"; alertCount += x.alertCount ?? 0; } } if (alertCount > 0) homeUnread = "mention"; const homeActive = typeof server === "undefined" && !path.startsWith("/invite"); return (
homeActive && openContextMenu("Status") }>
{servers.map((entry) => { const active = entry!._id === server?._id; const id = lastOpened[entry!._id]; return ( ); })} openScreen({ id: "special_input", type: "create_server", }) }>
); } export default connectState(ServerListSidebar, (state) => { return { unreads: state.unreads, lastOpened: state.lastOpened, }; });