Skip to content
Open
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 .github/workflows/app-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ jobs:
run: >-
T="$(date +%s)";

yarn build --prefix-paths;
yarn build --prefix-paths --profile;
exit_code=$?;

T="$(($(date +%s)-T))";
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ jobs:
run: >-
T="$(date +%s)";

yarn build --prefix-paths;
yarn build --prefix-paths --profile;
exit_code=$?;

T="$(($(date +%s)-T))";
Expand Down
8 changes: 7 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"node-fetch": "^2.6.0",
"polished": "^3.6.5",
"react": "^16.13.1",
"react-countup": "^4.3.3",
"react-data-grid": "^7.0.0-canary.17",
"react-dom": "^16.12.0",
"react-helmet": "^6.1.0",
Expand All @@ -57,16 +58,20 @@
"react-switch": "^5.0.1",
"react-transition-group": "^4.4.1",
"react-virtualized-auto-sizer": "^1.0.2",
"react-wordcloud": "^1.2.7",
"recharts": "^1.8.5",
"redux": "^4.0.5",
"redux-batched-actions": "^0.5.0",
"redux-saga": "^1.1.3",
"reselect": "^4.0.0",
"s-ago": "^2.2.0",
"shallow-equal": "^1.2.1",
"socket.io-client": "^2.3.0",
"ts-node": "^8.10.2",
"tsconfig-paths": "^3.9.0",
"twemoji": "^13.0.1",
"typescript": "^3.9.5"
"typescript": "^3.9.5",
"yarn": "^1.22.10"
},
"repository": {
"type": "git",
Expand All @@ -85,6 +90,7 @@
"@types/react-redux": "^7.1.9",
"@types/react-select": "^3.0.14",
"@types/react-virtualized-auto-sizer": "^1.0.0",
"@types/recharts": "^1.8.18",
"@types/socket.io-client": "^1.4.33",
"@types/twemoji": "^12.1.1",
"@types/underscore.string": "^0.0.38",
Expand Down
2 changes: 1 addition & 1 deletion app/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const GATEWAY_API_BASE: string = process.env.GATSBY_PRODUCTION
: "https://gateway.develop.archit.us";

/**
* resolves a path with he optional base path
* resolves a path with the optional base path
* @param path - base path with leading /
*/
export function withBasePath(path: string): string {
Expand Down
112 changes: 112 additions & 0 deletions app/src/components/CustomEmoji.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { styled } from "linaria/react";
import { transparentize } from "polished";
import React from "react";

import { OtherColors } from "@app/theme/color";
import { snowflakeToDate } from "@app/utility/discord";
import { CustomEmoji, Member, Snowflake } from "@app/utility/types";
import Tooltip from "@architus/facade/components/Tooltip";
import {
isDefined,
formatDateExtraShort,
formatNum,
} from "@architus/lib/utility";
import { gap } from "@architus/facade/theme/spacing";

const Styled = {
TooltipName: styled.strong`
display: block;
`,
TooltipElevated: styled.div`
opacity: 0.7;
font-size: 80%;
`,
OuterContainer: styled.div`
display: flex;
align-items: center;
justify-content: center;
img {
object-fit: cover;
width: 100%;
height: 90px;
margin-right: ${gap.nano};
max-width: 300px;
}
`,
InnerContainer: styled.div`
display: flex;
flex-direction: column;
flex-shrink: 0;
`,
ImageContainer: styled.div`
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;

img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
`,
PreviewContainer: styled.div`

`,
};

type CustomEmojiProps = {
emoji: CustomEmoji;
author?: Member;
className?: string;
style?: React.CSSProperties;
};

/**
* Wraps a CustomEmoji object in a formatted tooltip showing name, author name, creation date, and usage.
*/
export const CustomEmojiIcon: React.FC<CustomEmojiProps> = ({
emoji,
author,
style,
className,
}) => {
let authorName = null;
if (isDefined(author) && author.id === emoji.authorId.getOrElse("0" as Snowflake)) {
authorName = (
<Styled.TooltipElevated>
{author.name}#{author.discriminator}
</Styled.TooltipElevated>
);
}
const architusDate = snowflakeToDate((emoji.id as string) as Snowflake);
const discordDate = emoji.discordId.isDefined()
? snowflakeToDate(emoji.discordId.get)
: new Date(8640000000000000);
const date = formatDateExtraShort(
architusDate < discordDate ? architusDate : discordDate
);

return (
<Tooltip
maxWidth={"auto"}
tooltip={
<Styled.OuterContainer>
<img className={className} style={style} src={emoji.url} />
<Styled.InnerContainer>
<Styled.TooltipName>:{emoji.name}:</Styled.TooltipName>
{authorName}
<Styled.TooltipElevated>{date}</Styled.TooltipElevated>
<Styled.TooltipElevated>
uses: {formatNum(emoji.numUses)}
</Styled.TooltipElevated>
</Styled.InnerContainer>
</Styled.OuterContainer>
}
>
<Styled.ImageContainer>
<img className={className} style={style} src={emoji.url} />
</Styled.ImageContainer>
</Tooltip>
);
};
113 changes: 113 additions & 0 deletions app/src/components/Mention.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { styled } from "linaria/react";
import { transparentize } from "polished";
import React from "react";
import ago from "s-ago";

import { getAvatarUrl } from "@app/components/UserDisplay";
import { OtherColors } from "@app/theme/color";
import { Member } from "@app/utility/types";
import Tooltip from "@architus/facade/components/Tooltip";
import { gap } from "@architus/facade/theme/spacing";

const Styled = {
Tooltip: styled(Tooltip)``,
TooltipName: styled.strong`
display: block;
`,
TooltipElevated: styled.div`
opacity: 0.7;
font-size: 80%;
`,
Avatar: styled.img`
border-radius: 50%;
max-width: 70px;
height: auto;
margin: ${gap.pico} ${gap.nano} ${gap.pico} 0;
`,
OuterContainer: styled.div`
display: flex;
`,
InnerContainer: styled.div`
display: flex;
flex-direction: column;
justify-content: center;
white-space: nowrap;
text-align: left;
`,
NameContainer: styled.div<{ color: string }>`
border: 1px solid ${(props): string => props.color};
border-radius: 10px;
width: fit-content;
padding: 0 ${gap.femto} 0 ${gap.nano};
margin-bottom: ${gap.femto};
`,
ColoredCircle: styled.div<{ color: string }>`
height: 10px;
width: 10px;
background-color: ${(props): string => props.color};
border-radius: 50%;
display: inline-block;
margin: 0 ${gap.femto} 0 -${gap.pico};
`,
Mention: styled.div`
max-width: 100%;
color: ${OtherColors.Discord};
background-color: ${transparentize(0.85, OtherColors.Discord)};

& > p {
max-width: 100%;
}

&:hover {
color: white;
background-color: ${transparentize(0.25, OtherColors.Discord)};
}
`,
};

type MentionProps = {
member: Member;
className?: string;
style?: React.CSSProperties;
};

/**
* Render a Member object in the style of a discord mention in light or dark mode.
* Also wraps in a tooltip showing avatar, username, and join date.
*/
export const Mention: React.FC<MentionProps> = ({
member,
style,
className,
}) => {
let color = member.color.isDefined() ? member.color.get : "white";
if (color === "#000000") {
// because discord uses black instead of 'undefined'
color = "white";
}
return (
<Styled.Tooltip
maxWidth={"auto"}
tooltip={
<Styled.OuterContainer>
<Styled.Avatar
src={getAvatarUrl({ user: member, size: 64 }) ?? undefined}
/>
<Styled.InnerContainer>
<Styled.NameContainer color={color}>
<Styled.ColoredCircle color={color} />
{member.name}#{member.discriminator}
</Styled.NameContainer>
Joined {ago(new Date(member.joined_at))}
</Styled.InnerContainer>
</Styled.OuterContainer>
}
>
<Styled.Mention>
<p className={className} style={style}>
@{member.nick.isDefined() ? member.nick.get : member.name}
</p>
</Styled.Mention>
</Styled.Tooltip>
);
};
Loading