chore: server list integration test

This commit is contained in:
Paul Makles 2022-05-26 11:13:52 +01:00
parent 1e3fe45075
commit 94dd4b464a
4 changed files with 50 additions and 476 deletions

2
external/lang vendored

@ -1 +1 @@
Subproject commit a322d93399dac70a8bbb696eed6656edb0e37cd0 Subproject commit e08176d2e855e04628863c1495c3ce15624c2679

View file

@ -132,7 +132,7 @@
"markdown-it-emoji": "^2.0.0", "markdown-it-emoji": "^2.0.0",
"mediasoup-client": "npm:@insertish/mediasoup-client@3.6.36-esnext", "mediasoup-client": "npm:@insertish/mediasoup-client@3.6.36-esnext",
"mobx": "^6.6.0", "mobx": "^6.6.0",
"mobx-react-lite": "^3.3.0", "mobx-react-lite": "3.4.0",
"preact": "^10.5.14", "preact": "^10.5.14",
"preact-context-menu": "0.4.0-patch.0", "preact-context-menu": "0.4.0-patch.0",
"preact-i18n": "^2.4.0-preactx", "preact-i18n": "^2.4.0-preactx",
@ -144,7 +144,7 @@
"react-overlapping-panels": "1.2.2", "react-overlapping-panels": "1.2.2",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scroll": "^1.8.2", "react-scroll": "^1.8.2",
"react-virtuoso": "^1.10.4", "react-virtuoso": "^2.12.0",
"revolt.js": "6.0.0-2", "revolt.js": "6.0.0-2",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"sass": "^1.35.1", "sass": "^1.35.1",
@ -162,5 +162,8 @@
"repository": "https://github.com/revoltchat/revite.git", "repository": "https://github.com/revoltchat/revite.git",
"author": "Paul <paulmakles@gmail.com>", "author": "Paul <paulmakles@gmail.com>",
"license": "MIT", "license": "MIT",
"packageManager": "yarn@3.2.0" "packageManager": "yarn@3.2.0",
"resolutions": {
"@revoltchat/ui": "portal:../components"
}
} }

View file

@ -1,448 +1,25 @@
import { Plus } from "@styled-icons/boxicons-regular";
import { Cog, Compass } from "@styled-icons/boxicons-solid";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { Link, useHistory, useLocation, useParams } from "react-router-dom"; import { Link, useParams } from "react-router-dom";
import styled, { css } from "styled-components/macro";
import { useTriggerEvents } from "preact-context-menu"; import { ServerList } from "@revoltchat/ui";
import ConditionalLink from "../../../lib/ConditionalLink";
import PaintCounter from "../../../lib/PaintCounter";
import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
import { useApplicationState } from "../../../mobx/State";
import { SIDEBAR_CHANNELS } from "../../../mobx/stores/Layout";
import { useIntermediate } from "../../../context/intermediate/Intermediate";
import { useClient } from "../../../context/revoltjs/RevoltClient"; import { useClient } from "../../../context/revoltjs/RevoltClient";
import ChannelIcon from "../../common/ChannelIcon";
import ServerIcon from "../../common/ServerIcon";
import Tooltip from "../../common/Tooltip";
import UserHover from "../../common/user/UserHover";
import UserIcon from "../../common/user/UserIcon";
import IconButton from "../../ui/IconButton";
import LineDivider from "../../ui/LineDivider";
import { Children } from "../../../types/Preact";
function Icon({
children,
unread,
count,
size,
}: {
children: Children;
unread?: "mention" | "unread";
count: number | 0;
size: number;
}) {
return (
<svg width={size} height={size} aria-hidden="true" viewBox="0 0 32 32">
<use href="#serverIndicator" />
<foreignObject
x="0"
y="0"
width="32"
height="32"
mask={unread ? "url(#server)" : undefined}>
{children}
</foreignObject>
{unread === "unread" && (
<circle cx="27" cy="5" r="5" fill={"white"} />
)}
{unread === "mention" && (
<>
<circle cx="27" cy="5" r="5" fill={"var(--error)"} />
<text
x="27"
y="5"
r="5"
fill={"white"}
fontSize={"7.5"}
fontWeight={600}
text-anchor="middle"
alignmentBaseline={"middle"}
dominant-baseline={"middle"}>
{count < 10 ? count : "9+"}
</text>
</>
)}
</svg>
);
}
const ServersBase = styled.div`
width: 58px;
height: 100%;
padding-inline-start: 2px;
display: flex;
flex-shrink: 0;
flex-direction: column;
${isTouchscreenDevice &&
css`
padding-bottom: 50px;
`}
`;
const ServerList = styled.div`
flex-grow: 1;
display: flex;
overflow-y: scroll;
padding-bottom: 20px;
flex-direction: column;
scrollbar-width: none;
> :first-child > svg {
margin: 6px 0 6px 4px;
}
&::-webkit-scrollbar {
width: 0px;
}
`;
const ServerEntry = styled.div<{ active: boolean; home?: boolean }>`
height: 54px;
display: flex;
align-items: center;
//transition: 0.2s ease height;
:focus {
outline: 3px solid blue;
}
> div {
height: 42px;
padding-inline-start: 6px;
display: grid;
place-items: center;
border-start-start-radius: 50%;
border-end-start-radius: 50%;
&:active {
transform: translateY(1px);
}
${(props) =>
props.active &&
css`
&:active {
transform: none;
}
`}
}
> span {
width: 0;
display: relative;
${(props) =>
!props.active &&
css`
display: none;
`}
svg {
margin-top: 5px;
pointer-events: none;
}
}
${(props) =>
(!props.active || props.home) &&
css`
cursor: pointer;
`}
`;
const ServerCircle = styled.div`
width: 54px;
height: 54px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
.circle {
display: flex;
align-items: center;
justify-content: center;
background-color: var(--primary-background);
border-radius: 50%;
height: 42px;
width: 42px;
transition: background-color 0.1s ease-in;
cursor: pointer;
> div svg {
color: var(--accent);
}
&:active {
transform: translateY(1px);
}
}
`;
const SettingsButton = styled.div`
width: 50px;
height: 56px;
display: grid;
place-items: center;
`;
function Swoosh() {
const sidebarOpen = useApplicationState().layout.getSectionState(
SIDEBAR_CHANNELS,
true,
);
const fill = sidebarOpen
? "var(--sidebar-active)"
: "var(--primary-background)";
return (
<span>
<svg
width="56"
height="106"
viewBox="0 0 56 106"
xmlns="http://www.w3.org/2000/svg">
<path
d="M54 53C54 67.9117 41.9117 80 27 80C12.0883 80 0 67.9117 0 53C0 38.0883 12.0883 26 27 26C41.9117 26 54 38.0883 54 53Z"
fill={fill}
/>
<path
d="M27.0002 80C4.50023 80 56.0002 53 56.0002 53V106C56.0002 106 49.5002 80 27.0002 80Z"
fill={fill}
/>
<path
d="M27.0003 26C4.50025 26 56 53 56 53L56.0003 0C56.0003 0 49.5003 26 27.0003 26Z"
fill={fill}
/>
<rect x="51" y="50" width="5" height="7" fill={fill} />
</svg>
</span>
);
}
export default observer(() => { export default observer(() => {
const client = useClient(); const client = useClient();
const state = useApplicationState();
const { server: server_id } = useParams<{ server?: string }>(); const { server: server_id } = useParams<{ server?: string }>();
const server = server_id ? client.servers.get(server_id) : undefined;
const servers = [...client.servers.values()]; const servers = [...client.servers.values()];
const channels = [...client.channels.values()];
const history = useHistory();
const path = useLocation().pathname;
const { openScreen } = useIntermediate();
let alertCount = [...client.users.values()].filter(
(x) => x.relationship === "Incoming",
).length;
const homeActive =
typeof server === "undefined" &&
!path.startsWith("/invite") &&
!path.startsWith("/discover");
return ( return (
<ServersBase> <ServerList
<ServerList> active={server_id!}
<ConditionalLink servers={servers as any}
active={homeActive} linkComponent={({ id, children }) => (
to={state.layout.getLastHomePath()}> <Link to={`/server/${id}`}>
<ServerEntry home active={homeActive}> <a>{children}</a>
<Swoosh /> </Link>
<div
{...useTriggerEvents("Status")}
onClick={() =>
homeActive && history.push("/settings")
}>
<UserHover user={client.user ?? undefined}>
<Icon
size={42}
unread={
alertCount > 0 ? "mention" : undefined
}
count={alertCount}>
<UserIcon
target={client.user ?? undefined}
size={32}
status
hover
/>
</Icon>
</UserHover>
</div>
</ServerEntry>
</ConditionalLink>
{channels
.filter(
(x) =>
((x.channel_type === "DirectMessage" && x.active) ||
x.channel_type === "Group") &&
x.unread,
)
.map((x) => {
const unreadCount = x.mentions.length;
return (
<Link to={`/channel/${x._id}`}>
<ServerEntry
home
active={false}
{...useTriggerEvents("Menu", {
channel: x._id,
unread: true,
})}>
<div>
<Icon
size={42}
unread={
unreadCount > 0
? "mention"
: "unread"
}
count={unreadCount}>
{x.channel_type ===
"DirectMessage" ? (
<UserIcon
target={x.recipient}
size={32}
hover
/>
) : (
<ChannelIcon
target={x}
size={32}
hover
/>
)}
</Icon>
</div>
</ServerEntry>
</Link>
);
})}
<LineDivider />
{servers.map((server) => {
const active = server._id === server_id;
const isUnread = server.isUnread(state.notifications);
const mentionCount = server.getMentions(
state.notifications,
).length;
return (
<ConditionalLink
key={server._id}
active={active}
to={state.layout.getServerPath(server._id)}>
<ServerEntry
active={active}
{...useTriggerEvents("Menu", {
server: server._id,
unread: isUnread,
})}>
<Swoosh />
<Tooltip
content={server.name}
placement="right">
<Icon
size={42}
unread={
mentionCount > 0
? "mention"
: isUnread
? "unread"
: undefined
}
count={mentionCount}>
<ServerIcon size={32} target={server} />
</Icon>
</Tooltip>
</ServerEntry>
</ConditionalLink>
);
})}
{/*<LineDivider />*/}
<ServerCircle>
<Tooltip content="Add a Server" placement="right">
<div className="circle">
<IconButton
onClick={() =>
openScreen({
id: "special_input",
type: "create_server",
})
}>
<Plus size={32} />
</IconButton>
</div>
</Tooltip>
</ServerCircle>
{!isTouchscreenDevice && (
<ServerCircle>
<Tooltip
content={
<div
style={{
display: "flex",
alignItems: "center",
gap: "6px",
}}>
<div>Discover Revolt</div>
<div
style={{
padding: "1px 5px",
fontSize: "9px",
background: "var(--status-busy)",
borderRadius: "60px",
}}>
NEW
</div>
</div>
}
placement="right">
<div className="circle">
<IconButton>
<Link to="/discover">
<a>
<Compass size={32} />
</a>
</Link>
</IconButton>
</div>
</Tooltip>
</ServerCircle>
)}
</ServerList>
{!isTouchscreenDevice && (
<Tooltip content={"Settings"} placement="right">
<ServerCircle>
<Link to="/settings">
<div className="circle">
<IconButton>
<Cog
size={24}
fill="var(--secondary-foreground) !important"
/>
</IconButton>
</div>
</Link>
</ServerCircle>
</Tooltip>
)} )}
<PaintCounter small /> />
</ServersBase>
); );
}); });

View file

@ -2096,20 +2096,21 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@revoltchat/ui@npm:^1.0.31": "@revoltchat/ui@portal:../components::locator=client%40workspace%3A.":
version: 1.0.31 version: 0.0.0-use.local
resolution: "@revoltchat/ui@npm:1.0.31" resolution: "@revoltchat/ui@portal:../components::locator=client%40workspace%3A."
dependencies: dependencies:
"@styled-icons/boxicons-logos": ^10.38.0 "@styled-icons/boxicons-logos": ^10.38.0
"@styled-icons/boxicons-regular": ^10.38.0 "@styled-icons/boxicons-regular": ^10.38.0
"@styled-icons/boxicons-solid": ^10.38.0 "@styled-icons/boxicons-solid": ^10.38.0
mobx: ^6.5.0 mobx: ^6.6.0
mobx-react-lite: ^3.3.0 mobx-react-lite: ^3.4.0
react-beautiful-dnd: ^13.1.0
react-virtuoso: ^2.12.0
peerDependencies: peerDependencies:
revolt-api: "*" revolt-api: "*"
checksum: 8f93757d131ae7d784e744b774f6f6b9bea4e09a3fb48762334caf23e4ab08db209649eba1435f9fa82bdf7bfbfb78100fef6d13e7e0f715d0e2c82c52abf74d
languageName: node languageName: node
linkType: hard linkType: soft
"@rollup/plugin-babel@npm:^5.2.0": "@rollup/plugin-babel@npm:^5.2.0":
version: 5.3.0 version: 5.3.0
@ -2748,21 +2749,21 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@virtuoso.dev/react-urx@npm:^0.2.5": "@virtuoso.dev/react-urx@npm:^0.2.12":
version: 0.2.6 version: 0.2.13
resolution: "@virtuoso.dev/react-urx@npm:0.2.6" resolution: "@virtuoso.dev/react-urx@npm:0.2.13"
dependencies: dependencies:
"@virtuoso.dev/urx": ^0.2.6 "@virtuoso.dev/urx": ^0.2.13
peerDependencies: peerDependencies:
react: ">=16" react: ">=16"
checksum: 877760d0f4e56e4514a1f4f2e0160a99834b06b3c24bab32e569cadd06a3cb18e651bb60824a105d0abf4cc943630c2f68d0f461931b89f9e5f3ffff497f5c2b checksum: 173e91c21f6a8cd506ad3b72af10656897fe1951124ed9eeb1fd85575534993bea2f97cba3f81c08ae1e88a2613df348e2c80d0ceecb3021f8c8c8fe0e053ee2
languageName: node languageName: node
linkType: hard linkType: hard
"@virtuoso.dev/urx@npm:^0.2.5, @virtuoso.dev/urx@npm:^0.2.6": "@virtuoso.dev/urx@npm:^0.2.12, @virtuoso.dev/urx@npm:^0.2.13":
version: 0.2.6 version: 0.2.13
resolution: "@virtuoso.dev/urx@npm:0.2.6" resolution: "@virtuoso.dev/urx@npm:0.2.13"
checksum: d1942a81a828e250030a1a3dbf66545b1539c29c62d519b1bcaa1a45badf4e1baaa9efecf13238ca6c45555673fe5e12f3aba7d1c4fa2d7ab3e0a9a1504cf153 checksum: 682a99cf40ccc429241268dd37495cd1ed4695ae58b5a1169c75df1630d5dc3fd8eb3aaa655f71c37f39ba9c23c0aaf4401b76d8a986986d1a38a422d596a6ba
languageName: node languageName: node
linkType: hard linkType: hard
@ -3429,7 +3430,7 @@ __metadata:
markdown-it-emoji: ^2.0.0 markdown-it-emoji: ^2.0.0
mediasoup-client: "npm:@insertish/mediasoup-client@3.6.36-esnext" mediasoup-client: "npm:@insertish/mediasoup-client@3.6.36-esnext"
mobx: ^6.6.0 mobx: ^6.6.0
mobx-react-lite: ^3.3.0 mobx-react-lite: 3.4.0
preact: ^10.5.14 preact: ^10.5.14
preact-context-menu: 0.4.0-patch.0 preact-context-menu: 0.4.0-patch.0
preact-i18n: ^2.4.0-preactx preact-i18n: ^2.4.0-preactx
@ -3442,7 +3443,7 @@ __metadata:
react-overlapping-panels: 1.2.2 react-overlapping-panels: 1.2.2
react-router-dom: ^5.2.0 react-router-dom: ^5.2.0
react-scroll: ^1.8.2 react-scroll: ^1.8.2
react-virtuoso: ^1.10.4 react-virtuoso: ^2.12.0
revolt.js: 6.0.0-2 revolt.js: 6.0.0-2
rimraf: ^3.0.2 rimraf: ^3.0.2
sass: ^1.35.1 sass: ^1.35.1
@ -5845,18 +5846,18 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"mobx-react-lite@npm:^3.3.0": "mobx-react-lite@npm:3.4.0, mobx-react-lite@npm:^3.4.0":
version: 3.3.0 version: 3.4.0
resolution: "mobx-react-lite@npm:3.3.0" resolution: "mobx-react-lite@npm:3.4.0"
peerDependencies: peerDependencies:
mobx: ^6.1.0 mobx: ^6.1.0
react: ^16.8.0 || ^17 react: ^16.8.0 || ^17 || ^18
peerDependenciesMeta: peerDependenciesMeta:
react-dom: react-dom:
optional: true optional: true
react-native: react-native:
optional: true optional: true
checksum: 0f55bd2009a9cedc6b81d70b88b57dc4161362a16ba6ae0af341e673ca1c627bc3c4088c0cb13133e57e6fa6748b09b4c26aff7fab26c60ed95d27e939846fa3 checksum: 9294e127e281c8b37ec7bcaf17de479f50519e6ad485b58d7b991291900511541a5a718653759d3cf6503462c70325d025e1c2ed376d4584fb1b2d3aac9d9b48
languageName: node languageName: node
linkType: hard linkType: hard
@ -5867,7 +5868,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"mobx@npm:^6.5.0, mobx@npm:^6.6.0": "mobx@npm:^6.6.0":
version: 6.6.0 version: 6.6.0
resolution: "mobx@npm:6.6.0" resolution: "mobx@npm:6.6.0"
checksum: 369b8d6830ec286e9c856c80002c7a554d46bca739b7f76432cb56b3ce1fe0a7ed7e5a994b9793d30023beeff0dd16300a501e831fa97107104e4fedc7d4af8f checksum: 369b8d6830ec286e9c856c80002c7a554d46bca739b7f76432cb56b3ce1fe0a7ed7e5a994b9793d30023beeff0dd16300a501e831fa97107104e4fedc7d4af8f
@ -6509,16 +6510,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-virtuoso@npm:^1.10.4": "react-virtuoso@npm:^2.12.0":
version: 1.11.0 version: 2.12.0
resolution: "react-virtuoso@npm:1.11.0" resolution: "react-virtuoso@npm:2.12.0"
dependencies: dependencies:
"@virtuoso.dev/react-urx": ^0.2.5 "@virtuoso.dev/react-urx": ^0.2.12
"@virtuoso.dev/urx": ^0.2.5 "@virtuoso.dev/urx": ^0.2.12
resize-observer-polyfill: ^1.5.1
peerDependencies: peerDependencies:
react: ">=16" react: ">=16 || >=17 || >= 18"
checksum: bd0ba533a0a8a318d1fe5bd082a32ffcf1447a22dc8c9affa0d77c4ac9d7e8874ea806387e135788632dc27e189b7c0c26e78994d21c5db6015d563247ed2655 react-dom: ">=16 || >=17 || >= 18"
checksum: b40309cb6d5175bcfa8a6c648af35f14e051b31e2cb811298cbc5c37dd5179f0a307c20fa9e7232b4179d1ff3fd31599c747249899d1da5d11afd8ee659d7368
languageName: node languageName: node
linkType: hard linkType: hard
@ -6639,13 +6640,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"resize-observer-polyfill@npm:^1.5.1":
version: 1.5.1
resolution: "resize-observer-polyfill@npm:1.5.1"
checksum: 57e7f79489867b00ba43c9c051524a5c8f162a61d5547e99333549afc23e15c44fd43f2f318ea0261ea98c0eb3158cca261e6f48d66e1ed1cd1f340a43977094
languageName: node
linkType: hard
"resolve-from@npm:^4.0.0": "resolve-from@npm:^4.0.0":
version: 4.0.0 version: 4.0.0
resolution: "resolve-from@npm:4.0.0" resolution: "resolve-from@npm:4.0.0"