forked from abner/for-legacy-web
chore: merge branch 'ui/glass-header'
This commit is contained in:
@@ -4,84 +4,135 @@ import { observer } from "mobx-react-lite";
|
||||
import { Link } from "react-router-dom";
|
||||
import { ServerPermission } from "revolt.js/dist/api/permissions";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import styled from "styled-components";
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
|
||||
import Header from "../ui/Header";
|
||||
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
||||
|
||||
import IconButton from "../ui/IconButton";
|
||||
|
||||
import Tooltip from "./Tooltip";
|
||||
|
||||
interface Props {
|
||||
server: Server;
|
||||
background?: boolean;
|
||||
}
|
||||
|
||||
const ServerName = styled.div`
|
||||
flex-grow: 1;
|
||||
const ServerBanner = styled.div<Omit<Props, "server">>`
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: end;
|
||||
|
||||
background-size: cover;
|
||||
background-repeat: norepeat;
|
||||
background-position: center center;
|
||||
|
||||
${(props) =>
|
||||
props.background
|
||||
? css`
|
||||
height: 120px;
|
||||
|
||||
.container {
|
||||
background: linear-gradient(
|
||||
0deg,
|
||||
var(--secondary-background),
|
||||
transparent
|
||||
);
|
||||
}
|
||||
`
|
||||
: css`
|
||||
background-color: var(--secondary-header);
|
||||
`}
|
||||
|
||||
.container {
|
||||
height: var(--header-height);
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 14px;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
gap: 8px;
|
||||
|
||||
.title {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default observer(({ server }: Props) => {
|
||||
const bannerURL = server.generateBannerURL({ width: 480 });
|
||||
|
||||
return (
|
||||
<Header
|
||||
borders
|
||||
placement="secondary"
|
||||
<ServerBanner
|
||||
background={typeof bannerURL !== "undefined"}
|
||||
style={{
|
||||
background: bannerURL ? `url('${bannerURL}')` : undefined,
|
||||
backgroundImage: bannerURL ? `url('${bannerURL}')` : undefined,
|
||||
}}>
|
||||
{server.flags && server.flags & 1 ? (
|
||||
<Tooltip
|
||||
content={<Text id="app.special.server-badges.official" />}
|
||||
placement={"bottom-start"}>
|
||||
<svg width="20" height="20">
|
||||
<image
|
||||
xlinkHref="/assets/badges/verified.svg"
|
||||
height="20"
|
||||
width="20"
|
||||
/>
|
||||
<image
|
||||
xlinkHref="/assets/badges/revolt_r.svg"
|
||||
height="15"
|
||||
width="15"
|
||||
x="2"
|
||||
y="3"
|
||||
style={
|
||||
"justify-content: center; align-items: center; filter: brightness(0);"
|
||||
}
|
||||
/>
|
||||
</svg>
|
||||
</Tooltip>
|
||||
) : undefined}
|
||||
{server.flags && server.flags & 2 ? (
|
||||
<Tooltip
|
||||
content={<Text id="app.special.server-badges.verified" />}
|
||||
placement={"bottom-start"}>
|
||||
<svg width="20" height="20">
|
||||
<image
|
||||
xlinkHref="/assets/badges/verified.svg"
|
||||
height="20"
|
||||
width="20"
|
||||
/>
|
||||
<foreignObject x="2" y="2" width="15" height="15">
|
||||
<Check size={15} color="black" strokeWidth={8} />
|
||||
</foreignObject>
|
||||
</svg>
|
||||
</Tooltip>
|
||||
) : undefined}
|
||||
|
||||
<ServerName>{server.name}</ServerName>
|
||||
{(server.permission & ServerPermission.ManageServer) > 0 && (
|
||||
<div className="actions">
|
||||
<div className="container">
|
||||
{server.flags && server.flags & 1 ? (
|
||||
<Tooltip
|
||||
content={
|
||||
<Text id="app.special.server-badges.official" />
|
||||
}
|
||||
placement={"bottom-start"}>
|
||||
<svg width="20" height="20">
|
||||
<image
|
||||
xlinkHref="/assets/badges/verified.svg"
|
||||
height="20"
|
||||
width="20"
|
||||
/>
|
||||
<image
|
||||
xlinkHref="/assets/badges/revolt_r.svg"
|
||||
height="15"
|
||||
width="15"
|
||||
x="2"
|
||||
y="3"
|
||||
style={
|
||||
"justify-content: center; align-items: center; filter: brightness(0);"
|
||||
}
|
||||
/>
|
||||
</svg>
|
||||
</Tooltip>
|
||||
) : undefined}
|
||||
{server.flags && server.flags & 2 ? (
|
||||
<Tooltip
|
||||
content={
|
||||
<Text id="app.special.server-badges.verified" />
|
||||
}
|
||||
placement={"bottom-start"}>
|
||||
<svg width="20" height="20">
|
||||
<image
|
||||
xlinkHref="/assets/badges/verified.svg"
|
||||
height="20"
|
||||
width="20"
|
||||
/>
|
||||
<foreignObject x="2" y="2" width="15" height="15">
|
||||
<Check
|
||||
size={15}
|
||||
color="black"
|
||||
strokeWidth={8}
|
||||
/>
|
||||
</foreignObject>
|
||||
</svg>
|
||||
</Tooltip>
|
||||
) : undefined}
|
||||
<div className="title">{server.name}</div>
|
||||
{(server.permission & ServerPermission.ManageServer) > 0 && (
|
||||
<Link to={`/server/${server._id}/settings`}>
|
||||
<IconButton>
|
||||
<Cog size={24} />
|
||||
<Cog size={20} />
|
||||
</IconButton>
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</Header>
|
||||
)}
|
||||
</div>
|
||||
</ServerBanner>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -80,7 +80,7 @@ const Blocked = styled.div`
|
||||
color: var(--tertiary-foreground);
|
||||
|
||||
.text {
|
||||
padding: 14px 14px 14px 0;
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
svg {
|
||||
@@ -89,13 +89,17 @@ const Blocked = styled.div`
|
||||
`;
|
||||
|
||||
const Action = styled.div`
|
||||
display: flex;
|
||||
place-items: center;
|
||||
|
||||
> div {
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
padding: 12px;
|
||||
width: 34px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
/*padding: 14px 0 14px 14px;*/
|
||||
}
|
||||
|
||||
.mobile {
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
${() =>
|
||||
|
||||
@@ -13,19 +13,25 @@ export const Bar = styled.div<{ position: "top" | "bottom"; accent?: boolean }>`
|
||||
z-index: 10;
|
||||
position: relative;
|
||||
|
||||
${(props) =>
|
||||
props.position === "top" &&
|
||||
css`
|
||||
top: 0;
|
||||
`}
|
||||
|
||||
${(props) =>
|
||||
props.position === "bottom" &&
|
||||
css`
|
||||
top: 65px;
|
||||
|
||||
${() =>
|
||||
isTouchscreenDevice &&
|
||||
css`
|
||||
top: -90px;
|
||||
`}
|
||||
`}
|
||||
|
||||
> div {
|
||||
${(props) =>
|
||||
props.position === "bottom" &&
|
||||
css`
|
||||
top: -26px;
|
||||
|
||||
${() =>
|
||||
isTouchscreenDevice &&
|
||||
css`
|
||||
top: -32px;
|
||||
`}
|
||||
`}
|
||||
|
||||
height: 28px;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
@@ -52,6 +58,7 @@ export const Bar = styled.div<{ position: "top" | "bottom"; accent?: boolean }>`
|
||||
${(props) =>
|
||||
props.position === "top"
|
||||
? css`
|
||||
top: 48px;
|
||||
border-radius: 0 0 var(--border-radius)
|
||||
var(--border-radius);
|
||||
`
|
||||
@@ -60,6 +67,12 @@ export const Bar = styled.div<{ position: "top" | "bottom"; accent?: boolean }>`
|
||||
0;
|
||||
`}
|
||||
|
||||
${() =>
|
||||
isTouchscreenDevice &&
|
||||
css`
|
||||
top: 56px;
|
||||
`}
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -49,8 +49,12 @@ export default observer(
|
||||
}
|
||||
}}>
|
||||
<div>
|
||||
New messages since{" "}
|
||||
{dayjs(decodeTime(last_id)).fromNow()}
|
||||
<Text
|
||||
id="app.main.channel.misc.new_messages"
|
||||
fields={{
|
||||
time_ago: dayjs(decodeTime(last_id)).fromNow(),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Text id="app.main.channel.misc.jump_beginning" />
|
||||
|
||||
@@ -25,7 +25,11 @@ const Base = styled.div`
|
||||
flex-direction: row;
|
||||
width: calc(100% - var(--scrollbar-thickness));
|
||||
color: var(--secondary-foreground);
|
||||
background: var(--secondary-background);
|
||||
background-color: rgba(
|
||||
var(--secondary-background-rgb),
|
||||
max(var(--min-opacity), 0.75)
|
||||
);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.avatars {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Group } from "@styled-icons/boxicons-solid";
|
||||
import { autorun } from "mobx";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useHistory } from "react-router-dom";
|
||||
@@ -47,7 +48,7 @@ const EmbedInviteBase = styled.div`
|
||||
|
||||
const EmbedInviteDetails = styled.div`
|
||||
flex-grow: 1;
|
||||
padding-left: 12px;
|
||||
padding-inline-start: 12px;
|
||||
${() =>
|
||||
isTouchscreenDevice &&
|
||||
css`
|
||||
@@ -63,7 +64,14 @@ const EmbedInviteName = styled.div`
|
||||
`;
|
||||
|
||||
const EmbedInviteMemberCount = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
font-size: 0.8em;
|
||||
|
||||
> svg {
|
||||
color: var(--secondary-foreground);
|
||||
}
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
@@ -119,6 +127,7 @@ export function EmbedInvite({ code }: Props) {
|
||||
<EmbedInviteDetails>
|
||||
<EmbedInviteName>{invite.server_name}</EmbedInviteName>
|
||||
<EmbedInviteMemberCount>
|
||||
<Group size={12} />
|
||||
{invite.member_count.toLocaleString()}{" "}
|
||||
{invite.member_count === 1 ? "member" : "members"}
|
||||
</EmbedInviteMemberCount>
|
||||
|
||||
@@ -17,10 +17,10 @@ const Base = styled.div`
|
||||
`;
|
||||
|
||||
const Navbar = styled.div`
|
||||
z-index: 100;
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
z-index: 500;
|
||||
display: flex;
|
||||
margin: 0 auto;
|
||||
max-width: 500px;
|
||||
height: var(--bottom-navigation-height);
|
||||
`;
|
||||
|
||||
@@ -71,7 +71,12 @@ export default observer(() => {
|
||||
}
|
||||
}
|
||||
|
||||
history.push(layout.getLastHomePath());
|
||||
const path = layout.getLastHomePath();
|
||||
if (path === "/friends") {
|
||||
history.push("/");
|
||||
} else {
|
||||
history.push(path);
|
||||
}
|
||||
}}>
|
||||
<Message size={24} />
|
||||
</IconButton>
|
||||
|
||||
@@ -8,6 +8,13 @@ export default styled.div`
|
||||
user-select: none;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
/*background: var(--background);*/
|
||||
|
||||
background-color: rgba(
|
||||
var(--background-rgb),
|
||||
max(var(--min-opacity), 0.75)
|
||||
);
|
||||
backdrop-filter: blur(20px);
|
||||
`;
|
||||
|
||||
export const GenericSidebarBase = styled.div<{
|
||||
@@ -21,10 +28,15 @@ export const GenericSidebarBase = styled.div<{
|
||||
/*border-end-start-radius: 8px;*/
|
||||
background: var(--secondary-background);
|
||||
|
||||
> :nth-child(1) {
|
||||
border-end-start-radius: 8px;
|
||||
/*> :nth-child(1) {
|
||||
//border-end-start-radius: 8px;
|
||||
}
|
||||
|
||||
> :nth-child(2) {
|
||||
margin-top: 48px;
|
||||
background: red;
|
||||
}*/
|
||||
|
||||
${(props) =>
|
||||
props.mobilePadding &&
|
||||
isTouchscreenDevice &&
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { X, Crown } from "@styled-icons/boxicons-regular";
|
||||
import { X } from "@styled-icons/boxicons-regular";
|
||||
import { Crown } from "@styled-icons/boxicons-solid";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Presence } from "revolt-api/types/Users";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Link, useLocation, useParams } from "react-router-dom";
|
||||
import { RelationshipStatus } from "revolt-api/types/Users";
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useEffect } from "preact/hooks";
|
||||
@@ -27,6 +28,21 @@ import { GenericSidebarBase, GenericSidebarList } from "../SidebarBase";
|
||||
import ButtonItem, { ChannelButton } from "../items/ButtonItem";
|
||||
import ConnectionStatus from "../items/ConnectionStatus";
|
||||
|
||||
const Navbar = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 14px;
|
||||
font-weight: 600;
|
||||
flex-shrink: 0;
|
||||
height: 48px;
|
||||
|
||||
${() =>
|
||||
isTouchscreenDevice &&
|
||||
css`
|
||||
height: 56px;
|
||||
`}
|
||||
`;
|
||||
|
||||
export default observer(() => {
|
||||
const { pathname } = useLocation();
|
||||
const client = useContext(AppContext);
|
||||
@@ -55,6 +71,9 @@ export default observer(() => {
|
||||
|
||||
return (
|
||||
<GenericSidebarBase mobilePadding>
|
||||
<Navbar>
|
||||
<Text id="app.home.directs" />
|
||||
</Navbar>
|
||||
<ConnectionStatus />
|
||||
<GenericSidebarList>
|
||||
<ConditionalLink active={pathname === "/"} to="/">
|
||||
|
||||
@@ -95,6 +95,7 @@ const ServerList = styled.div`
|
||||
overflow-y: scroll;
|
||||
padding-bottom: 20px;
|
||||
flex-direction: column;
|
||||
margin-top: -2px;
|
||||
|
||||
scrollbar-width: none;
|
||||
|
||||
@@ -168,6 +169,7 @@ const ServerCircle = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
.circle {
|
||||
display: flex;
|
||||
@@ -384,7 +386,7 @@ export default observer(() => {
|
||||
</div>
|
||||
</Tooltip>
|
||||
</ServerCircle>
|
||||
<ServerCircle>
|
||||
{/*<ServerCircle>
|
||||
<Tooltip
|
||||
content={
|
||||
<div
|
||||
@@ -394,14 +396,13 @@ export default observer(() => {
|
||||
gap: "4px",
|
||||
}}>
|
||||
<div>Discover Public Servers</div>
|
||||
<LinkExternal size={12} />
|
||||
</div>
|
||||
}
|
||||
placement="right">
|
||||
<div className="circle">
|
||||
<IconButton>
|
||||
<a
|
||||
href="https://revolt.social"
|
||||
href="#"
|
||||
target="_blank"
|
||||
rel="noreferrer">
|
||||
<Compass size={32} />
|
||||
@@ -409,7 +410,7 @@ export default observer(() => {
|
||||
</IconButton>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</ServerCircle>
|
||||
</ServerCircle>*/}
|
||||
</ServerList>
|
||||
<PaintCounter small />
|
||||
{!isTouchscreenDevice && (
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Redirect, useParams } from "react-router";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
import { attachContextMenu } from "preact-context-menu";
|
||||
@@ -48,6 +49,10 @@ const ServerList = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
server: Server;
|
||||
}
|
||||
|
||||
export default observer(() => {
|
||||
const client = useClient();
|
||||
const state = useApplicationState();
|
||||
|
||||
@@ -6,9 +6,12 @@ import { Presence } from "revolt-api/types/Users";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
import { useContext, useEffect, useMemo } from "preact/hooks";
|
||||
|
||||
import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
|
||||
|
||||
import {
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
@@ -18,6 +21,15 @@ import {
|
||||
import { GenericSidebarBase } from "../SidebarBase";
|
||||
import MemberList, { MemberListGroup } from "./MemberList";
|
||||
|
||||
export const Container = styled.div`
|
||||
padding-top: 48px;
|
||||
|
||||
${isTouchscreenDevice &&
|
||||
css`
|
||||
padding-top: 0;
|
||||
`}
|
||||
`;
|
||||
|
||||
export default function MemberSidebar() {
|
||||
const channel = useClient().channels.get(
|
||||
useParams<{ channel: string }>().channel,
|
||||
@@ -157,6 +169,10 @@ export const GroupMemberSidebar = observer(
|
||||
|
||||
return (
|
||||
<GenericSidebarBase>
|
||||
<Container>
|
||||
{/*{isTouchscreenDevice && <div>Group settings go here</div>}*/}
|
||||
</Container>
|
||||
|
||||
<MemberList entries={entries} context={channel} />
|
||||
</GenericSidebarBase>
|
||||
);
|
||||
@@ -180,6 +196,9 @@ export const ServerMemberSidebar = observer(
|
||||
|
||||
return (
|
||||
<GenericSidebarBase>
|
||||
<Container>
|
||||
{/*{isTouchscreenDevice && <div>Server settings go here</div>}*/}
|
||||
</Container>
|
||||
<MemberList entries={entries} context={channel} />
|
||||
</GenericSidebarBase>
|
||||
);
|
||||
|
||||
@@ -218,28 +218,32 @@ export const DisplaySeasonalShim = observer(() => {
|
||||
const settings = useApplicationState().settings;
|
||||
|
||||
return (
|
||||
<>
|
||||
<h3>
|
||||
<Text id="app.settings.pages.appearance.theme_options.title" />
|
||||
</h3>
|
||||
{/* TOFIX: WIP feature - follows system theme */}
|
||||
{/*<Checkbox
|
||||
checked={settings.get("appearance:seasonal") ?? true}
|
||||
onChange={(v) => settings.set("appearance:seasonal", v)}
|
||||
description={
|
||||
<Text id="app.settings.pages.appearance.theme_options.follow_desc" />
|
||||
}>
|
||||
<Text id="app.settings.pages.appearance.theme_options.follow" />
|
||||
</Checkbox>*/}
|
||||
<Checkbox
|
||||
checked={settings.get("appearance:seasonal") ?? true}
|
||||
onChange={(v) => settings.set("appearance:seasonal", v)}
|
||||
description={
|
||||
<Text id="app.settings.pages.appearance.theme_options.seasonal_desc" />
|
||||
}>
|
||||
<Text id="app.settings.pages.appearance.theme_options.seasonal" />
|
||||
</Checkbox>
|
||||
</>
|
||||
<Checkbox
|
||||
checked={settings.get("appearance:seasonal") ?? true}
|
||||
onChange={(v) => settings.set("appearance:seasonal", v)}
|
||||
description={
|
||||
<Text id="app.settings.pages.appearance.theme_options.seasonal_desc" />
|
||||
}>
|
||||
<Text id="app.settings.pages.appearance.theme_options.seasonal" />
|
||||
</Checkbox>
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Component providing a way to toggle transparency effects.
|
||||
*/
|
||||
export const DisplayTransparencyShim = observer(() => {
|
||||
const settings = useApplicationState().settings;
|
||||
|
||||
return (
|
||||
<Checkbox
|
||||
checked={settings.get("appearance:transparency") ?? true}
|
||||
onChange={(v) => settings.set("appearance:transparency", v)}
|
||||
description={
|
||||
<Text id="app.settings.pages.appearance.theme_options.transparency_desc" />
|
||||
}>
|
||||
<Text id="app.settings.pages.appearance.theme_options.transparency" />
|
||||
</Checkbox>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -19,4 +19,8 @@ export default styled.select`
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 1.5pt var(--accent);
|
||||
}
|
||||
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
`;
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
||||
|
||||
export default styled.details<{ sticky?: boolean; large?: boolean }>`
|
||||
summary {
|
||||
${(props) =>
|
||||
props.sticky &&
|
||||
css`
|
||||
top: -1px;
|
||||
top: 48px;
|
||||
z-index: 10;
|
||||
position: sticky;
|
||||
${() =>
|
||||
isTouchscreenDevice &&
|
||||
css`
|
||||
top: 56px;
|
||||
`}
|
||||
`}
|
||||
|
||||
${(props) =>
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
Menu,
|
||||
} from "@styled-icons/boxicons-regular";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
||||
@@ -14,14 +15,16 @@ import { SIDEBAR_CHANNELS } from "../../mobx/stores/Layout";
|
||||
import { Children } from "../../types/Preact";
|
||||
|
||||
interface Props {
|
||||
borders?: boolean;
|
||||
topBorder?: boolean;
|
||||
bottomBorder?: boolean;
|
||||
|
||||
background?: boolean;
|
||||
transparent?: boolean;
|
||||
placement: "primary" | "secondary";
|
||||
}
|
||||
|
||||
const Header = styled.div<Props>`
|
||||
gap: 10px;
|
||||
height: 48px;
|
||||
flex: 0 auto;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
@@ -29,15 +32,11 @@ const Header = styled.div<Props>`
|
||||
font-weight: 600;
|
||||
user-select: none;
|
||||
align-items: center;
|
||||
|
||||
height: var(--header-height);
|
||||
|
||||
background-size: cover !important;
|
||||
background-position: center !important;
|
||||
background-color: var(--primary-header);
|
||||
|
||||
/*> div {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}*/
|
||||
|
||||
svg {
|
||||
flex-shrink: 0;
|
||||
@@ -48,11 +47,21 @@ const Header = styled.div<Props>`
|
||||
color: var(--secondary-foreground);
|
||||
}
|
||||
|
||||
${() =>
|
||||
isTouchscreenDevice &&
|
||||
css`
|
||||
height: 56px;
|
||||
`}
|
||||
${(props) =>
|
||||
props.transparent
|
||||
? css`
|
||||
background-color: rgba(
|
||||
var(--primary-header-rgb),
|
||||
max(var(--min-opacity), 0.75)
|
||||
);
|
||||
backdrop-filter: blur(10px);
|
||||
z-index: 20;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
`
|
||||
: css`
|
||||
background-color: var(--primary-header);
|
||||
`}
|
||||
|
||||
${(props) =>
|
||||
props.background &&
|
||||
@@ -71,10 +80,16 @@ const Header = styled.div<Props>`
|
||||
`}
|
||||
|
||||
${(props) =>
|
||||
props.borders &&
|
||||
props.topBorder &&
|
||||
css`
|
||||
border-start-start-radius: 8px;
|
||||
`}
|
||||
|
||||
${(props) =>
|
||||
props.bottomBorder &&
|
||||
css`
|
||||
border-end-start-radius: 8px;
|
||||
`}
|
||||
`;
|
||||
|
||||
export default Header;
|
||||
@@ -98,19 +113,24 @@ const IconContainer = styled.div`
|
||||
`}
|
||||
`;
|
||||
|
||||
interface PageHeaderProps {
|
||||
type PageHeaderProps = Omit<Props, "placement" | "borders"> & {
|
||||
noBurger?: boolean;
|
||||
children: Children;
|
||||
icon: Children;
|
||||
}
|
||||
};
|
||||
|
||||
export const PageHeader = observer(
|
||||
({ children, icon, noBurger }: PageHeaderProps) => {
|
||||
({ children, icon, noBurger, ...props }: PageHeaderProps) => {
|
||||
const layout = useApplicationState().layout;
|
||||
const visible = layout.getSectionState(SIDEBAR_CHANNELS, true);
|
||||
const { pathname } = useLocation();
|
||||
|
||||
return (
|
||||
<Header placement="primary" borders={!visible}>
|
||||
<Header
|
||||
{...props}
|
||||
placement="primary"
|
||||
topBorder={!visible}
|
||||
bottomBorder={!pathname.includes("/server")}>
|
||||
{!noBurger && <HamburgerAction />}
|
||||
<IconContainer
|
||||
onClick={() =>
|
||||
@@ -135,7 +155,7 @@ export function HamburgerAction() {
|
||||
|
||||
function openSidebar() {
|
||||
document
|
||||
.querySelector("#app > div > div")
|
||||
.querySelector("#app > div > div > div")
|
||||
?.scrollTo({ behavior: "smooth", left: 0 });
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import styled from "styled-components";
|
||||
|
||||
export default styled.div`
|
||||
height: 0px;
|
||||
height: 0;
|
||||
opacity: 0.6;
|
||||
flex-shrink: 0;
|
||||
margin: 8px 10px;
|
||||
margin: 8px 15px;
|
||||
border-top: 1px solid var(--tertiary-foreground);
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user