Add new blog components and post

This commit is contained in:
Kevin Kandlbinder 2022-02-05 17:16:03 +00:00 committed by GitHub
parent b35ad08052
commit a352600428
16 changed files with 440 additions and 5 deletions

View file

@ -0,0 +1,58 @@
import React, { useEffect, useRef, useState } from "react";
import anime, { AnimeTimelineInstance } from "animejs";
import _uniqueId from 'lodash/uniqueId';
import {useMediaQuery} from '@react-hook/media-query'
import * as styles from "./Chatbox.module.scss";
const Chatblah = () => {
const animeRef = useRef<AnimeTimelineInstance>(null)
const [myId,] = useState(_uniqueId)
const reduceMotion = useMediaQuery("(prefers-reduced-motion: reduce)")
useEffect(() => {
if(typeof window === "undefined") return; // Don't run on static build
if(reduceMotion) return; // Don't run the animation for users who prefer reduced motion
const speed = 0.25;
const delay = anime.random(100/speed, 1000/speed);
animeRef.current = anime.timeline({
targets: "#chatblah-"+myId,
loop: true,
easing: "easeInOutSine"
})
const tl = animeRef.current
tl.add({
duration: 250/speed,
opacity: [0, .25],
easing: "linear"
}, delay).add({
duration: 1000/speed,
rotate: [anime.random(-5, 5)+"deg", anime.random(-10, 10)+"deg"],
translateY: [0, anime.random(0, -2)+"px"],
translateX: [0, anime.random(-2, 2)+"px"],
}, delay).add({
duration: 500/speed,
opacity: [.25, 0],
easing: "linear"
}, delay+(500/speed))
return () => {
if(animeRef.current) {
animeRef.current.pause();
animeRef.current = null;
}
}
}, [myId, reduceMotion])
return <div className={styles.chatBlah} id={"chatblah-"+myId}>
<span>blah</span>
</div>
}
export default Chatblah

View file

@ -0,0 +1,138 @@
@use "sass:math";
@use "sass:map";
@import "../../globals";
.screenReader {
opacity: 0.001;
width: 1px;
height: 1px;
margin: -1px;
position: absolute;
overflow: hidden;
white-space: nowrap;
padding: 0;
}
.chatbox {
display: flex;
flex-direction: column;
padding: $layoutPadding;
margin: $layoutPadding (-$layoutPadding);
background-color: rgba(gray, 0.1);
border-radius: 10px;
&.openBottom {
border-radius: 10px 10px 0 0;
margin-bottom: 20px;
background-image: linear-gradient(
to top,
$background,
transparent 20px
);
}
&.openBoth {
border-radius: 0;
margin-top: 20px;
margin-bottom: 20px;
background-image: linear-gradient(to top, $background, transparent 20px),
linear-gradient(to bottom, $background, transparent 20px);
}
&.openTop {
border-radius: 0 0 10px 10px;
margin-top: 20px;
background-image: linear-gradient(
to bottom,
$background,
transparent 20px
);
}
@media (prefers-color-scheme: light) {
&.openBottom {
background-image: linear-gradient(
to top,
$lightBackground,
transparent 20px
);
}
&.openBoth {
background-image: linear-gradient(
to top,
$lightBackground,
transparent 20px
),
linear-gradient(to bottom, $lightBackground, transparent 20px);
}
&.openTop {
background-image: linear-gradient(
to bottom,
$lightBackground,
transparent 20px
);
}
}
}
.chatnotice {
display: flex;
justify-content: center;
margin: math.div($layoutPadding, 2) $layoutPadding;
> span {
max-width: 500px;
opacity: 0.75;
font-style: italic;
text-align: center;
}
}
.chatmsg {
display: flex;
flex-direction: column;
margin: 0 $layoutPadding;
align-items: flex-start;
--msg-color: #{map.get($theme, "blue")};
&.alignRight {
align-items: flex-end;
--msg-color: #{$accentColor};
}
.name {
margin: 5px;
}
.chatbubble {
position: relative;
padding: math.div($layoutPadding, 2) $layoutPadding;
border-radius: 10px;
border: thin solid var(--msg-color);
max-width: 700px;
hr {
display: block;
margin: math.div($layoutPadding, 2) (-$layoutPadding);
border: none;
border-top: thin solid var(--msg-color);
}
}
}
.chatBlah {
display: inline-block;
margin: 0 5px;
opacity: 0.25;
&:first-child {
margin-left: 0;
}
}

View file

@ -0,0 +1,11 @@
export const alignRight: string;
export const chatBlah: string;
export const chatbox: string;
export const chatbubble: string;
export const chatmsg: string;
export const chatnotice: string;
export const name: string;
export const openBoth: string;
export const openBottom: string;
export const openTop: string;
export const screenReader: string;

View file

@ -0,0 +1,20 @@
import React from "react";
import { useTranslation } from "react-i18next";
import * as styles from "./Chatbox.module.scss";
type ChatboxProps = {
open?: string
}
const Chatbox = ({children, open}: React.PropsWithChildren<ChatboxProps>) => {
const {t} = useTranslation();
return <div className={styles.chatbox + (open === "top" ? " " + styles.openTop : "") + (open === "bottom" ? " " + styles.openBottom : "") + (open === "both" ? " " + styles.openBoth : "")}>
<span className={styles.screenReader}>-- {open === "top" || open === "both" ? t("blog.scambox.chatbox.resume") : t("blog.scambox.chatbox.begin")} --</span>
{children}
<span className={styles.screenReader}>-- {open === "bottom" || open === "both" ? t("blog.scambox.chatbox.interrupt") : t("blog.scambox.chatbox.end")} --</span>
</div>
}
export default Chatbox

View file

@ -0,0 +1,27 @@
import React from "react";
import { useTranslation } from "react-i18next";
import * as styles from "./Chatbox.module.scss"
type ChatmsgProps = {
name?: string,
timestamp?: string,
color?: string,
dir: string
}
const Chatmsg = (props: React.PropsWithChildren<ChatmsgProps>) => {
const {t} = useTranslation();
return <div className={styles.chatmsg + (props.dir === "out" ? " " + styles.alignRight : "")}>
{props.name && <span className={styles.name}>{props.name}<span className={styles.screenReader}> {t("blog.scambox.chatbox.says")}</span></span>}
<div className={styles.chatbubble}>
<div>
{props.children}
</div>
{props.timestamp && <span>{props.timestamp}</span>}
</div>
</div>
}
export default Chatmsg

View file

@ -0,0 +1,11 @@
import React from "react";
import * as styles from "./Chatbox.module.scss"
const Chatnotice = (props: React.PropsWithChildren<{}>) => {
return <div className={styles.chatnotice}>
<span>{props.children}</span>
</div>
}
export default Chatnotice