feat(home): add snow

This commit is contained in:
Paul 2021-12-23 13:16:43 +00:00
parent f14ef2b78f
commit 73d99e4518
4 changed files with 200 additions and 63 deletions

View file

@ -5,7 +5,6 @@ import classNames from "classnames";
import { attachContextMenu } from "preact-context-menu"; import { attachContextMenu } from "preact-context-menu";
import { useContext, useState } from "preact/hooks"; import { useContext, useState } from "preact/hooks";
import { useIntermediate } from "../../../../context/intermediate/Intermediate";
import { AppContext } from "../../../../context/revoltjs/RevoltClient"; import { AppContext } from "../../../../context/revoltjs/RevoltClient";
import AttachmentActions from "./AttachmentActions"; import AttachmentActions from "./AttachmentActions";
@ -39,7 +38,7 @@ export default function Attachment({ attachment, hasContent }: Props) {
width={metadata.width} width={metadata.width}
height={metadata.height} height={metadata.height}
onContextMenu={attachContextMenu("Menu", { onContextMenu={attachContextMenu("Menu", {
attachment: attachment, attachment,
})} })}
className={classNames({ className={classNames({
[styles.margin]: hasContent, [styles.margin]: hasContent,

View file

@ -1,4 +1,5 @@
.home { .home {
height: 100%;
user-select: none; user-select: none;
h3 { h3 {

View file

@ -3,8 +3,9 @@ import { Link } from "react-router-dom";
import styled, { css } from "styled-components"; import styled, { css } from "styled-components";
import styles from "./Home.module.scss"; import styles from "./Home.module.scss";
import "./snow.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useContext, useState } from "preact/hooks"; import { useContext, useMemo, useState } from "preact/hooks";
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice"; import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
@ -32,6 +33,19 @@ const IconConainer = styled.div`
`} `}
`; `;
const Overlay = styled.div`
display: grid;
height: 100%;
> * {
grid-area: 1 / 1;
}
.content {
z-index: 1;
}
`;
export default function Home() { export default function Home() {
const client = useContext(AppContext); const client = useContext(AppContext);
const [showChannels, setChannels] = useState( const [showChannels, setChannels] = useState(
@ -59,68 +73,102 @@ export default function Home() {
} }
}; };
const snowflakes = useMemo(() => {
const flakes = [];
// Disable outside of December
if (new Date().getMonth() !== 11) return [];
for (let i = 0; i < 15; i++) {
flakes.push("❄️");
flakes.push("❄");
}
for (let i = 0; i < 2; i++) {
flakes.push("🎄");
flakes.push("☃️");
flakes.push("⛄");
}
return flakes;
}, []);
return ( return (
<div className={styles.home}> <div className={styles.home}>
<Header placement="primary"> <Overlay>
<IconConainer onClick={toggleChannelSidebar}> <div class="snowfall">
<HomeIcon size={24} /> {snowflakes.map((emoji, index) => (
</IconConainer> <div key={index} class="snowflake">
<Text id="app.navigation.tabs.home" /> {emoji}
</Header> </div>
<h3> ))}
<Text id="app.special.modals.onboarding.welcome" /> </div>
<br /> <div class="content">
<img src={wideSVG} /> <Header placement="primary">
</h3> <IconConainer onClick={toggleChannelSidebar}>
<div className={styles.actions}> <HomeIcon size={24} />
<Link to="/invite/Testers"> </IconConainer>
<CategoryButton <Text id="app.navigation.tabs.home" />
action="chevron" </Header>
icon={<Emoji emoji="😁" size={32} />}> <h3>
{client.servers.get("01F7ZSBSFHQ8TA81725KQCSDDP") ? ( <Text id="app.special.modals.onboarding.welcome" />
<Text id="app.home.goto-testers" /> <br />
) : ( <img src={wideSVG} />
<Text id="app.home.join-testers" /> </h3>
)} <div className={styles.actions}>
</CategoryButton> <Link to="/invite/Testers">
</Link> <CategoryButton
<a action="chevron"
href="https://insrt.uk/donate" icon={<Emoji emoji="😁" size={32} />}>
target="_blank" {client.servers.get(
rel="noreferrer"> "01F7ZSBSFHQ8TA81725KQCSDDP",
<CategoryButton ) ? (
action="external" <Text id="app.home.goto-testers" />
icon={<Emoji emoji="💷" size={32} />}> ) : (
<Text id="app.home.donate" /> <Text id="app.home.join-testers" />
</CategoryButton> )}
</a> </CategoryButton>
<Link to="/settings/feedback"> </Link>
<CategoryButton <a
action="chevron" href="https://insrt.uk/donate"
icon={<Emoji emoji="🎉" size={32} />}> target="_blank"
<Text id="app.home.feedback" /> rel="noreferrer">
</CategoryButton> <CategoryButton
</Link> action="external"
<a icon={<Emoji emoji="💷" size={32} />}>
href="https://revolt.social" <Text id="app.home.donate" />
target="_blank" </CategoryButton>
rel="noreferrer"> </a>
<CategoryButton <Link to="/settings/feedback">
action="external" <CategoryButton
icon={<Emoji emoji="🧭" size={32} />}> action="chevron"
<Text id="app.home.social" /> icon={<Emoji emoji="🎉" size={32} />}>
</CategoryButton> <Text id="app.home.feedback" />
</a> </CategoryButton>
<Tooltip content={<Text id="app.home.settings-tooltip" />}> </Link>
<Link to="/settings"> <a
<CategoryButton href="https://revolt.social"
action="chevron" target="_blank"
icon={<Emoji emoji="🔧" size={32} />}> rel="noreferrer">
<Text id="app.home.settings" /> <CategoryButton
</CategoryButton> action="external"
</Link> icon={<Emoji emoji="🧭" size={32} />}>
</Tooltip> <Text id="app.home.social" />
</div> </CategoryButton>
</a>
<Tooltip
content={<Text id="app.home.settings-tooltip" />}>
<Link to="/settings">
<CategoryButton
action="chevron"
icon={<Emoji emoji="🔧" size={32} />}>
<Text id="app.home.settings" />
</CategoryButton>
</Link>
</Tooltip>
</div>
</div>
</Overlay>
</div> </div>
); );
} }

89
src/pages/home/snow.scss Normal file
View file

@ -0,0 +1,89 @@
// Pure CSS Snowfall
// Released by Artimon under MIT license
$count: 36;
$screenOffset: 0px;
$fallDuration: 12;
$windNoise: 30;
$windSpeed: 4;
$sizeNoise: 40;
$rotation: 360;
$imageSize: 20px;
$fontSize: 40px;
.snowfall {
z-index: 0;
display: block;
font-size: $fontSize;
overflow: hidden;
pointer-events: none;
.snowflake {
position: relative;
top: 0;
left: 0;
display: flex;
justify-content: center;
width: $screenOffset;
height: $screenOffset;
span {
align-self: center;
}
img {
align-self: center;
width: $imageSize;
}
}
@while ($count > 0) {
$left: random(100);
$deltaLeft: random(2 * $windNoise * 10) / 10 - $windNoise + $windSpeed;
$scale: 1 + (random(2 * $sizeNoise * 10) / 10 - $sizeNoise) / 100;
.snowflake:nth-child(#{$count}) {
animation: animation-snowflake-#{$count} linear infinite;
animation-duration: $fallDuration +
random($fallDuration * 10) /
10 +
s;
animation-delay: random(2 * $fallDuration * 10) /
10 -
(2 * $fallDuration) +
s;
}
@keyframes animation-snowflake-#{$count} {
0% {
left: percentage($left / 100);
top: calc(0% - #{$screenOffset});
transform: scale($scale)
rotate3d(
random(100) / 100,
random(100) / 100,
random(100) / 100,
0deg
);
}
100% {
left: percentage(($left + $deltaLeft) / 100);
top: calc(100% + #{$screenOffset});
transform: scale($scale)
rotate3d(
random(100) / 100,
random(100) / 100,
random(100) / 100,
(random($rotation) + $rotation) *
((random(2) - 1) * 2 - 1) + deg
);
}
}
$count: $count - 1;
}
}