mirror of
https://github.com/revoltchat/revite.git
synced 2024-12-25 23:22:06 -05:00
feat(home): add snow
This commit is contained in:
parent
f14ef2b78f
commit
73d99e4518
4 changed files with 200 additions and 63 deletions
|
@ -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,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
.home {
|
.home {
|
||||||
|
height: 100%;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
|
|
|
@ -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
89
src/pages/home/snow.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue