Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/src/app/(navfooter)/faq/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ReactNode } from "react";

import Link from "next/link";

import Frog from "@/components/Nav/frog.svg";
import Frog from "@/components/Frog/Frog";

const subtitle = "mt-8 text-xl font-semibold tracking-tight text-gray-11";

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ChevronRightIcon } from "@primer/octicons-react";

import GhostButton from "@/components/GhostButton";
import Frog from "@/components/Nav/frog.svg";
import Frog from "@/components/Frog/Frog";

export default function NotFound() {
return (
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { MarkGithubIcon } from "@primer/octicons-react";

import DiscordIcon from "./discord.svg";
import GhostButton from "./GhostButton";
import Logotype from "./Logotype";
import SiteLogo from "./Nav/SiteLogo";

function Separator() {
return <div className="hidden h-4 w-px bg-gray-6 sm:inline-block" />;
Expand All @@ -20,7 +20,7 @@ export default function Footer() {
<div className="border-gray-6 border-t py-10">
<div className="flex items-center justify-center">
<Link href="/">
<Logotype />
<SiteLogo />
</Link>
</div>
<div className="mt-4 flex flex-col items-center justify-center gap-1 sm:flex-row sm:gap-2">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import type { SVGProps } from "react";

import clsx from "clsx";

import type * as api from "@/lib/api";

import Frog from "../Nav/frog.svg";

import styles from "./AnonymousFrog.module.scss";
import Frog from "./Frog";

export type Props = SVGProps<SVGElement> & {
user: api.AnonymousUser;
Expand All @@ -18,11 +14,11 @@ export default function AnonymousFrogAvatar({
className,
...props
}: Props) {
const accentStyle = {
"--accent-hue": user.frog_color[0],
"--accent-saturation": user.frog_color[1],
"--accent-lightness": user.frog_color[2],
};
const [hue, saturation, lightness] = user.frog_color;

const primary = `hsl(${hue}, ${saturation * 100}%, ${lightness * 100}%)`;
const secondary = `hsl(${hue}, ${(0.3 * (1 - saturation) + saturation) * 100}%, ${(0.5 * (1 - lightness) + lightness) * 100}%)`;
const nose = `hsl(${hue}, ${(saturation - 0.2 * saturation) * 100}%, ${(lightness - 0.4 * lightness) * 100}%)`;

return (
<div
Expand All @@ -32,8 +28,10 @@ export default function AnonymousFrogAvatar({
)}
>
<Frog
style={accentStyle}
className={clsx(styles.anonymousFrog, "h-4/6 w-4/6")}
primary={primary}
secondary={secondary}
nose={nose}
className="h-4/6 w-4/6"
{...props}
/>
</div>
Expand Down
31 changes: 31 additions & 0 deletions frontend/src/components/Frog/Frog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from "react";

const Frog = ({
primary = "#951fd9",
secondary = "#cc87f4",
pupil = "#000",
eye = "#FFF",
nose = "#505050",
title = "",
...props
}) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" {...props}>
<title>{title}</title>
<path
fill={secondary}
d="M36 22c0 7.456-8.059 12-18 12S0 29.456 0 22 8.059 7 18 7s18 7.544 18 15z"
/>
<path
fill={primary}
d="M31.755 12.676C33.123 11.576 34 9.891 34 8c0-3.313-2.687-6-6-6-2.861 0-5.25 2.004-5.851 4.685-1.288-.483-2.683-.758-4.149-.758-1.465 0-2.861.275-4.149.758C13.25 4.004 10.861 2 8 2 4.687 2 2 4.687 2 8c0 1.891.877 3.576 2.245 4.676C1.6 15.356 0 18.685 0 22c0 7.456 8.059 1 18 1s18 6.456 18-1c0-3.315-1.6-6.644-4.245-9.324z"
/>
<circle fill={eye} cx="7.5" cy="7.5" r="3.5" className="eyeL" />
<circle fill={pupil} cx="7.5" cy="7.5" r="1.5" className="pupilL" />
<circle fill={eye} cx="28.5" cy="7.5" r="3.5" className="eyeR" />
<circle fill={pupil} cx="28.5" cy="7.5" r="1.5" className="pupilR" />
<circle fill={nose} cx="14" cy="20" r="1" className="noseL" />
<circle fill={nose} cx="22" cy="20" r="1" className="noseR" />
</svg>
);

export default Frog;
66 changes: 66 additions & 0 deletions frontend/src/components/Frog/HolidayFrog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from "react";
import Frog from "./Frog";

interface HolidayFrogProps {
today?: Date;
className?: string;
}

export default function HolidayFrog({
today = new Date(),
className = "size-7",
}: HolidayFrogProps) {
const month = today.getUTCMonth();
const date = today.getUTCDate();

// TODO: special handling for frug
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes


// Defaults
let primary = "#951fd9";
let secondary = "#cc87f4";
let message = "Happy Decomping!";

if (month === 1 && date === 14) {
primary = "#e6396f";
secondary = "#f7a1c4";
message = "❤️ Happy Valentine's Day! ❤️";
}
if (month === 2 && date === 17) {
primary = "#2a9d34";
secondary = "#7fd28d";
message = "🍀 Happy St Patrick's Day! 🍀";
}
if (month === 9 && date === 31) {
primary = "#d96516";
secondary = "#20150aff";
message = "🎃 Happy Halloween! 🎃";
}

if (month === 10) {
// Thanksgiving (4th Thursday of November)
const firstDay = new Date(today.getFullYear(), 10, 1);
const firstThursday = 1 + ((4 - firstDay.getDay() + 7) % 7);
const fourthThursday = firstThursday + 21;
if (date === fourthThursday) {
primary = "#9e682a";
secondary = "#d2a679";
message = "🦃 Happy Thanksgiving! 🦃";
}
}

if (month === 11 && date === 25) {
primary = "#E61A1A";
secondary = "#F8BFBF";
message = "🎅 Merry Christmas! 🎅";
}

return (
<Frog
className={className}
aria-label="Purple frog"
primary={primary}
secondary={secondary}
title={message}
/>
);
}
15 changes: 0 additions & 15 deletions frontend/src/components/Logotype.tsx

This file was deleted.

41 changes: 0 additions & 41 deletions frontend/src/components/Nav/Nav.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -64,47 +64,6 @@ $padding: 8px;
width: 100%;
height: 100%;
}

&:not(:hover) {
@keyframes blink {
0% {
transform: scaleY(1);
opacity: 1;
}

25% {
transform: scaleY(0.2);
opacity: 0;
}

50% {
transform: scaleY(1);
opacity: 1;
}

75% {
transform: scaleY(0.2);
opacity: 0;
}

100% {
transform: scaleY(1);
opacity: 1;
}
}

:global(.frog_svg__pupilR),
:global(.frog_svg__pupilL),
:global(.frog_svg__eyeR),
:global(.frog_svg__eyeL) {
transform-origin: 0 7px;
animation: blink 0.4s 2s ease;

@media (prefers-reduced-motion) {
animation: none;
}
}
}
}

.menu {
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/Nav/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ThreeBarsIcon, XIcon } from "@primer/octicons-react";
import clsx from "clsx";

import GhostButton from "../GhostButton";
import Logotype from "../Logotype";
import SiteLogo from "./SiteLogo";

import LoginState from "./LoginState";
import styles from "./Nav.module.scss";
Expand Down Expand Up @@ -71,7 +71,7 @@ export default function Nav({ children }: Props) {
href="/"
className="transition-colors hover:text-gray-12 active:translate-y-px"
>
<Logotype />
<SiteLogo />
</Link>
</li>
<li className={styles.headerItemLoginState}>
Expand Down Expand Up @@ -108,7 +108,7 @@ export default function Nav({ children }: Props) {
<ul className={styles.links}>
<li className="flex items-center justify-center">
<Link href="/">
<Logotype />
<SiteLogo />
</Link>
</li>
<li>
Expand Down
39 changes: 39 additions & 0 deletions frontend/src/components/Nav/SiteLogo.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
@keyframes blink {
0% {
transform: scaleY(1);
opacity: 1;
}
25% {
transform: scaleY(0.2);
opacity: 0;
}
50% {
transform: scaleY(1);
opacity: 1;
}
75% {
transform: scaleY(0.2);
opacity: 0;
}
100% {
transform: scaleY(1);
opacity: 1;
}
}

.blinkingEyes :global(.pupilR),
.blinkingEyes :global(.pupilL),
.blinkingEyes :global(.eyeR),
.blinkingEyes :global(.eyeL) {
transform-origin: 0 7px;
animation: blink 0.4s 2s ease;
}

@media (prefers-reduced-motion) {
.blinkingEyes :global(.pupilR),
.blinkingEyes :global(.pupilL),
.blinkingEyes :global(.eyeR),
.blinkingEyes :global(.eyeL) {
animation: none;
}
}
20 changes: 20 additions & 0 deletions frontend/src/components/Nav/SiteLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import clsx from "clsx";
import HolidayFrog from "../Frog/HolidayFrog";
import styles from "./SiteLogo.module.scss";

export default function SiteLogo() {
return (
<div
className={clsx(
"inline-flex items-center space-x-2",
styles.blinkingEyes,
)}
aria-label="decomp.me logo"
>
<HolidayFrog />
<span className="font-semibold text-xl leading-6 tracking-tight">
decomp.me
</span>
</div>
);
}
11 changes: 0 additions & 11 deletions frontend/src/components/Nav/frog.svg

This file was deleted.

2 changes: 1 addition & 1 deletion frontend/src/components/ScratchItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { presetUrl, scratchUrl, userAvatarUrl } from "@/lib/api/urls";

import getTranslation from "@/lib/i18n/translate";

import AnonymousFrogAvatar from "./user/AnonymousFrog";
import AnonymousFrogAvatar from "./Frog/AnonymousFrog";
import PlatformLink from "./PlatformLink";
import { calculateScorePercent, percentToString } from "./ScoreBadge";
import styles from "./ScratchItem.module.scss";
Expand Down
27 changes: 0 additions & 27 deletions frontend/src/components/user/AnonymousFrog.module.scss

This file was deleted.

2 changes: 1 addition & 1 deletion frontend/src/components/user/UserAvatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import clsx from "clsx";
import * as api from "@/lib/api";
import { userAvatarUrl } from "@/lib/api/urls";

import AnonymousFrogAvatar from "./AnonymousFrog";
import AnonymousFrogAvatar from "../Frog/AnonymousFrog";
import styles from "./UserAvatar.module.scss";

export type Props = {
Expand Down