mirror of
https://github.com/stoatchat/for-legacy-web.git
synced 2026-03-09 02:05:28 +00:00
Remove seasonal effects and set invite links on landing page
This commit is contained in:
@@ -59,18 +59,6 @@ export default function AppearanceOptions() {
|
|||||||
<Text id="app.settings.pages.appearance.theme_options.transparency_desc" />
|
<Text id="app.settings.pages.appearance.theme_options.transparency_desc" />
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{/* Option to toggle seasonal effects. */}
|
|
||||||
<ObservedInputElement
|
|
||||||
type="checkbox"
|
|
||||||
value={() => settings.get("appearance:seasonal") ?? true}
|
|
||||||
onChange={(v) => settings.set("appearance:seasonal", v)}
|
|
||||||
title={
|
|
||||||
<Text id="app.settings.pages.appearance.theme_options.seasonal" />
|
|
||||||
}
|
|
||||||
description={
|
|
||||||
<Text id="app.settings.pages.appearance.theme_options.seasonal_desc" />
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Column>
|
</Column>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ export interface ISettings {
|
|||||||
|
|
||||||
"appearance:emoji": EmojiPack;
|
"appearance:emoji": EmojiPack;
|
||||||
"appearance:ligatures": boolean;
|
"appearance:ligatures": boolean;
|
||||||
"appearance:seasonal": boolean;
|
|
||||||
"appearance:transparency": boolean;
|
"appearance:transparency": boolean;
|
||||||
"appearance:show_send_button": boolean;
|
"appearance:show_send_button": boolean;
|
||||||
"appearance:show_account_age": boolean;
|
"appearance:show_account_age": boolean;
|
||||||
@@ -129,7 +128,6 @@ export default class Settings
|
|||||||
) {
|
) {
|
||||||
if (key === "appearance") {
|
if (key === "appearance") {
|
||||||
this.remove("appearance:emoji");
|
this.remove("appearance:emoji");
|
||||||
this.remove("appearance:seasonal");
|
|
||||||
this.remove("appearance:transparency");
|
this.remove("appearance:transparency");
|
||||||
} else {
|
} else {
|
||||||
this.remove("appearance:ligatures");
|
this.remove("appearance:ligatures");
|
||||||
@@ -159,7 +157,6 @@ export default class Settings
|
|||||||
const data: Record<"appearance" | "theme", Partial<ISettings>> = {
|
const data: Record<"appearance" | "theme", Partial<ISettings>> = {
|
||||||
appearance: this.pullKeys([
|
appearance: this.pullKeys([
|
||||||
"appearance:emoji",
|
"appearance:emoji",
|
||||||
"appearance:seasonal",
|
|
||||||
"appearance:transparency",
|
"appearance:transparency",
|
||||||
]),
|
]),
|
||||||
theme: this.pullKeys([
|
theme: this.pullKeys([
|
||||||
|
|||||||
@@ -1,37 +1,27 @@
|
|||||||
import { Money } from "@styled-icons/boxicons-regular";
|
|
||||||
import {
|
import {
|
||||||
Home as HomeIcon,
|
Home as HomeIcon,
|
||||||
PlusCircle,
|
MessageDots,
|
||||||
Compass,
|
MessageAdd,
|
||||||
Megaphone,
|
Lock,
|
||||||
Group,
|
|
||||||
Cog,
|
|
||||||
RightArrowCircle,
|
|
||||||
} from "@styled-icons/boxicons-solid";
|
} from "@styled-icons/boxicons-solid";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import styled from "styled-components/macro";
|
import styled from "styled-components/macro";
|
||||||
|
|
||||||
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 { useMemo } from "preact/hooks";
|
|
||||||
|
|
||||||
import { CategoryButton } from "@revoltchat/ui";
|
import { CategoryButton } from "@revoltchat/ui";
|
||||||
|
|
||||||
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
|
||||||
|
|
||||||
import { useApplicationState } from "../../mobx/State";
|
|
||||||
|
|
||||||
import wideSVG from "/assets/wide.svg";
|
import wideSVG from "/assets/wide.svg";
|
||||||
|
|
||||||
import { PageHeader } from "../../components/ui/Header";
|
import { PageHeader } from "../../components/ui/Header";
|
||||||
import { useClient } from "../../controllers/client/ClientController";
|
import { useClient } from "../../controllers/client/ClientController";
|
||||||
import { modalController } from "../../controllers/modals/ModalController";
|
|
||||||
|
|
||||||
const Overlay = styled.div`
|
const Overlay = styled.div`
|
||||||
display: grid;
|
display: grid;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
grid-area: 1 / 1;
|
grid-area: 1 / 1;
|
||||||
@@ -40,65 +30,137 @@ const Overlay = styled.div`
|
|||||||
.content {
|
.content {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
padding-top: 1rem;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const DisabledButtonWrapper = styled.div`
|
||||||
|
opacity: 0.5;
|
||||||
|
pointer-events: none;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default observer(() => {
|
export default observer(() => {
|
||||||
const client = useClient();
|
const client = useClient();
|
||||||
const state = useApplicationState();
|
|
||||||
|
|
||||||
const seasonalTheme = state.settings.get("appearance:seasonal", true);
|
const servers = [
|
||||||
const toggleSeasonalTheme = () =>
|
{
|
||||||
state.settings.set("appearance:seasonal", !seasonalTheme);
|
id: "01J544PT4T3WQBVBSDK3TBFZW7",
|
||||||
|
name: "PepChat Official",
|
||||||
|
description:
|
||||||
|
"Get your questions answered and stay up-to-date with the state of the project.",
|
||||||
|
inviteCode: "pepchatdiscover",
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "01J5ZQMJSQ5AFZJJ3S204JK5Q4",
|
||||||
|
name: "Elite Group Buy (EGB)",
|
||||||
|
description: "Group buy peptides, amino blends & more.",
|
||||||
|
inviteCode: "elitegroupbuydiscover",
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "01J63A8HQ8S10MM4B3K85VMYBW",
|
||||||
|
name: "Wonderland",
|
||||||
|
description: "Peptide life social group.",
|
||||||
|
inviteCode: "wonderlanddiscover",
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "01J545CBXQRWZZAASZQ6THKE96",
|
||||||
|
name: "Qingdao Sigma Chemical (QSC)",
|
||||||
|
description:
|
||||||
|
"China wholesale bioactive compounds. (International, US, EU, Canada and Australia domestic)",
|
||||||
|
inviteCode: "qscdiscover",
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "01J5TQYA639STTEX7SH5KXC96M",
|
||||||
|
name: "Joe Lu's Hideout",
|
||||||
|
description: "Peptide group buys.",
|
||||||
|
inviteCode: "placeholder",
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "01J64CC6710N7CCWBBT625VXQ3",
|
||||||
|
name: "The Raven Nest",
|
||||||
|
description:
|
||||||
|
"Group buys, protocols, social, and all things peptides.",
|
||||||
|
inviteCode: "placeholder",
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "01J5Z5QBQWREPZZPMVKJNCBDP2",
|
||||||
|
name: "Joyous",
|
||||||
|
description: "Peptide group buys.",
|
||||||
|
inviteCode: "placeholder",
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "01J5VPXSS0EK69QD69RX6SKZHW",
|
||||||
|
name: "Kimmes Korner",
|
||||||
|
description: "Peptide group buys.",
|
||||||
|
inviteCode: "placeholder",
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "placeholder",
|
||||||
|
name: "Polypeptide Universe",
|
||||||
|
description: "The science of peptides in depth.",
|
||||||
|
inviteCode: "placeholder",
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "placeholder",
|
||||||
|
name: "Deb's Peptalk",
|
||||||
|
description:
|
||||||
|
"Group buys, protocols, social, and all things peptides.",
|
||||||
|
inviteCode: "placeholder",
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const isDecember = !isTouchscreenDevice && new Date().getMonth() === 11;
|
const renderServerButton = (server) => {
|
||||||
const isOctober = !isTouchscreenDevice && new Date().getMonth() === 9
|
const isServerJoined = client.servers.get(server.id);
|
||||||
const snowflakes = useMemo(() => {
|
const linkTo = isServerJoined
|
||||||
const flakes: string[] = [];
|
? `/server/${server.id}`
|
||||||
|
: `/invite/${server.inviteCode}`;
|
||||||
|
|
||||||
if (isDecember) {
|
const buttonContent = (
|
||||||
for (let i = 0; i < 15; i++) {
|
<CategoryButton
|
||||||
flakes.push("❄️");
|
key={server.id}
|
||||||
flakes.push("❄");
|
action={server.disabled ? undefined : "chevron"}
|
||||||
}
|
icon={
|
||||||
|
server.disabled ? (
|
||||||
|
<Lock size={32} />
|
||||||
|
) : isServerJoined ? (
|
||||||
|
<MessageDots size={32} />
|
||||||
|
) : (
|
||||||
|
<MessageAdd size={32} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
description={server.description}>
|
||||||
|
{server.name}
|
||||||
|
</CategoryButton>
|
||||||
|
);
|
||||||
|
|
||||||
for (let i = 0; i < 2; i++) {
|
if (server.disabled) {
|
||||||
flakes.push("🎄");
|
return (
|
||||||
flakes.push("☃️");
|
<DisabledButtonWrapper>{buttonContent}</DisabledButtonWrapper>
|
||||||
flakes.push("⛄");
|
);
|
||||||
}
|
} else {
|
||||||
|
return (
|
||||||
return flakes;
|
<Link to={linkTo} key={server.id}>
|
||||||
|
{buttonContent}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (isOctober) {
|
};
|
||||||
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 flakes;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.home}>
|
<div className={styles.home}>
|
||||||
<Overlay>
|
<Overlay>
|
||||||
{seasonalTheme && (
|
|
||||||
<div className="snowfall">
|
|
||||||
{snowflakes.map((emoji, index) => (
|
|
||||||
<div key={index} className="snowflake">
|
|
||||||
{emoji}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<PageHeader icon={<HomeIcon size={24} />} withTransparency>
|
<PageHeader icon={<HomeIcon size={24} />} withTransparency>
|
||||||
<Text id="app.navigation.tabs.home" />
|
<Text id="app.navigation.tabs.home" />
|
||||||
@@ -110,100 +172,8 @@ export default observer(() => {
|
|||||||
<img src={wideSVG} />
|
<img src={wideSVG} />
|
||||||
</h3>
|
</h3>
|
||||||
<div className={styles.actions}>
|
<div className={styles.actions}>
|
||||||
<a
|
{servers.map(renderServerButton)}
|
||||||
onClick={() =>
|
|
||||||
modalController.push({
|
|
||||||
type: "create_group",
|
|
||||||
})
|
|
||||||
}>
|
|
||||||
<CategoryButton
|
|
||||||
action="chevron"
|
|
||||||
icon={<PlusCircle size={32} />}
|
|
||||||
description={
|
|
||||||
<Text id="app.home.group_desc" />
|
|
||||||
}>
|
|
||||||
<Text id="app.home.group" />
|
|
||||||
</CategoryButton>
|
|
||||||
</a>
|
|
||||||
<Link to="/discover">
|
|
||||||
<a>
|
|
||||||
<CategoryButton
|
|
||||||
action="chevron"
|
|
||||||
icon={<Compass size={32} />}
|
|
||||||
description={
|
|
||||||
<Text id="app.home.discover_desc" />
|
|
||||||
}>
|
|
||||||
<Text id="app.home.discover" />
|
|
||||||
</CategoryButton>
|
|
||||||
</a>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
{client.servers.get(
|
|
||||||
"01F7ZSBSFHQ8TA81725KQCSDDP",
|
|
||||||
) ? (
|
|
||||||
<Link to="/server/01F7ZSBSFHQ8TA81725KQCSDDP">
|
|
||||||
<CategoryButton
|
|
||||||
action="chevron"
|
|
||||||
icon={<RightArrowCircle size={32} />}
|
|
||||||
description={
|
|
||||||
<Text id="app.home.goto-testers_desc" />
|
|
||||||
}>
|
|
||||||
<Text id="app.home.goto-testers" />
|
|
||||||
</CategoryButton>
|
|
||||||
</Link>
|
|
||||||
) : (
|
|
||||||
<Link to="/invite/Testers">
|
|
||||||
<CategoryButton
|
|
||||||
action="chevron"
|
|
||||||
icon={<Group size={32} />}
|
|
||||||
description={
|
|
||||||
<Text id="app.home.join-testers_desc" />
|
|
||||||
}>
|
|
||||||
<Text id="app.home.join-testers" />
|
|
||||||
</CategoryButton>
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Link to="/settings/feedback">
|
|
||||||
<CategoryButton
|
|
||||||
action="chevron"
|
|
||||||
icon={<Megaphone size={32} />}
|
|
||||||
description={
|
|
||||||
<Text id="app.home.feedback_desc" />
|
|
||||||
}>
|
|
||||||
<Text id="app.home.feedback" />
|
|
||||||
</CategoryButton>
|
|
||||||
</Link>
|
|
||||||
<a
|
|
||||||
href="https://insrt.uk/donate"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer">
|
|
||||||
<CategoryButton
|
|
||||||
action="external"
|
|
||||||
description={
|
|
||||||
<Text id="app.home.donate_desc" />
|
|
||||||
}
|
|
||||||
icon={<Money size={32} />}>
|
|
||||||
<Text id="app.home.donate" />
|
|
||||||
</CategoryButton>
|
|
||||||
</a>
|
|
||||||
<Link to="/settings">
|
|
||||||
<CategoryButton
|
|
||||||
action="chevron"
|
|
||||||
description={
|
|
||||||
<Text id="app.home.settings-tooltip" />
|
|
||||||
}
|
|
||||||
icon={<Cog size={32} />}>
|
|
||||||
<Text id="app.home.settings" />
|
|
||||||
</CategoryButton>
|
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
{isDecember && (
|
|
||||||
<a href="#" onClick={toggleSeasonalTheme}>
|
|
||||||
Turn {seasonalTheme ? "off" : "on"} homescreen
|
|
||||||
effects
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Overlay>{" "}
|
</Overlay>{" "}
|
||||||
|
|||||||
@@ -1,98 +0,0 @@
|
|||||||
// Pure CSS Snowfall
|
|
||||||
// Released by Artimon under MIT license
|
|
||||||
//
|
|
||||||
// Source: https://github.com/Artimon/pure-css-snowfall
|
|
||||||
|
|
||||||
@use 'sass:math';
|
|
||||||
|
|
||||||
$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: math.div(
|
|
||||||
random(2 * $windNoise * 10),
|
|
||||||
10 - $windNoise + $windSpeed
|
|
||||||
);
|
|
||||||
$scale: 1 +
|
|
||||||
math.div(
|
|
||||||
math.div(random(2 * $sizeNoise * 10), 10 - $sizeNoise),
|
|
||||||
100
|
|
||||||
);
|
|
||||||
|
|
||||||
.snowflake:nth-child(#{$count}) {
|
|
||||||
animation: animation-snowflake-#{$count} linear infinite;
|
|
||||||
animation-duration: $fallDuration +
|
|
||||||
math.div(random($fallDuration * 10), 10) +
|
|
||||||
s;
|
|
||||||
animation-delay: math.div(random(2 * $fallDuration * 10), 10) -
|
|
||||||
(2 * $fallDuration) +
|
|
||||||
s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes animation-snowflake-#{$count} {
|
|
||||||
0% {
|
|
||||||
left: percentage(math.div($left, 100));
|
|
||||||
top: calc(0% - #{$screenOffset});
|
|
||||||
transform: scale($scale)
|
|
||||||
rotate3d(
|
|
||||||
math.div(random(100), 100),
|
|
||||||
math.div(random(100), 100),
|
|
||||||
math.div(random(100), 100),
|
|
||||||
0deg
|
|
||||||
);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
left: percentage(math.div(($left + $deltaLeft), 100));
|
|
||||||
top: calc(100% + #{$screenOffset});
|
|
||||||
transform: scale($scale)
|
|
||||||
rotate3d(
|
|
||||||
math.div(random(100), 100),
|
|
||||||
math.div(random(100), 100),
|
|
||||||
math.div(random(100), 100),
|
|
||||||
(random($rotation) + $rotation) *
|
|
||||||
((random(2) - 1) * 2 - 1) + deg
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$count: $count - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user