diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..6ff29e5 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,25 @@ +on: push +name: lint + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout project + uses: actions/checkout@v2 + with: + clean: false + + - name: Use Node.js 14 + uses: actions/setup-node@v1 + with: + node-version: 14.x + + - name: Install deps + run: yarn + + - name: Run ESLint + run: yarn lint + env: + CI: true diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..51b5141 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "quoteProps": "consistent", + "printWidth": 120, + "bracketSpacing": true, + "singleQuote": false, + "useTabs": false, + "arrowParens": "avoid", + "tabWidth": 4 +} diff --git a/package.json b/package.json index 3a41903..3572d88 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@types/react": "17.0.11", "eslint": "7.28.0", "eslint-config-next": "11.0.0", + "prettier": "^2.3.1", "typescript": "4.3.3" } } diff --git a/pages/_app.tsx b/pages/_app.tsx index ab0b18c..c201566 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,5 +1,18 @@ -import type { AppProps } from 'next/app' +import type { AppProps } from "next/app"; +import Head from "next/head"; export default function LanyardReadMe({ Component, pageProps }: AppProps) { - return + return ( + <> + + + + + + + + + + + ); } diff --git a/pages/_document.js b/pages/_document.js index 7511a5a..f967ac0 100644 --- a/pages/_document.js +++ b/pages/_document.js @@ -1,30 +1,29 @@ -import Document from 'next/document' -import { ServerStyleSheet } from 'styled-components' +import Document from "next/document"; +import { ServerStyleSheet } from "styled-components"; export default class MyDocument extends Document { - static async getInitialProps(ctx) { - const sheet = new ServerStyleSheet(), - originalRenderPage = ctx.renderPage + static async getInitialProps(ctx) { + const sheet = new ServerStyleSheet(), + originalRenderPage = ctx.renderPage; - try { - ctx.renderPage = () => - originalRenderPage({ - enhanceApp: (App) => (props) => - sheet.collectStyles(), - }) + try { + ctx.renderPage = () => + originalRenderPage({ + enhanceApp: App => props => sheet.collectStyles(), + }); - const initialProps = await Document.getInitialProps(ctx) - return { - ...initialProps, - styles: ( - <> - {initialProps.styles} - {sheet.getStyleElement()} - - ), - } - } finally { - sheet.seal() + const initialProps = await Document.getInitialProps(ctx); + return { + ...initialProps, + styles: ( + <> + {initialProps.styles} + {sheet.getStyleElement()} + + ), + }; + } finally { + sheet.seal(); + } } - } -} \ No newline at end of file +} diff --git a/pages/api/[...id].ts b/pages/api/[...id].ts index d9792c3..502e403 100644 --- a/pages/api/[...id].ts +++ b/pages/api/[...id].ts @@ -4,8 +4,8 @@ import renderCard from "../../src/renderCard"; import { isSnowflake } from "../../src/snowflake"; type Data = { - id?: string | string[]; - error?: any; + id?: string | string[]; + error?: any; }; type Parameters = { @@ -14,38 +14,34 @@ type Parameters = { hideStatus?: string; hideDiscrim?: string; borderRadius?: string; - animated?: string; + animated?: string; }; -export default async function handler( - req: NextApiRequest, - res: NextApiResponse, -) { - const params: Parameters = req.query, - userid = req.query.id[0]; +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + let axiosRes; + const params: Parameters = req.query, + userid = req.query.id[0]; - if (!isSnowflake(userid)) - return res.send({ - error: `Specify a valid Discord user ID! If everything looks correct and this still occurs, please contact @cnraddd on Twitter.`, - }); + if (!isSnowflake(userid)) + return res.send({ + error: `Specify a valid Discord user ID! If everything looks correct and this still occurs, please contact @cnraddd on Twitter.`, + }); - let err: any; - const axiosRes = await axios - .get(`https://api.lanyard.rest/v1/users/${userid}`) - .catch((e) => (err = e)); + try { + axiosRes = await axios.get(`https://api.lanyard.rest/v1/users/${userid}`); + } catch (err) { + console.log(err); - if (err) console.log(err); - if (err || axiosRes.status != 200) - return res.send({ - error: `Something went wrong! If everything looks correct and this still occurs, please contact @cnraddd on Twitter.`, - }); + if (err.response.status === 404) return res.send({ error: "Invalid user!" }); - res.setHeader("Content-Type", "image/svg+xml; charset=utf-8"); - res.setHeader( - "content-security-policy", - "default-src 'none'; img-src * data:; style-src 'unsafe-inline'", - ); + return res.send({ + error: `Something went wrong! If everything looks correct and this still occurs, please contact @cnraddd on Twitter.`, + }); + } - let svg = await renderCard(axiosRes.data, params); - res.status(200).send(svg as any); + res.setHeader("Content-Type", "image/svg+xml; charset=utf-8"); + res.setHeader("content-security-policy", "default-src 'none'; img-src * data:; style-src 'unsafe-inline'"); + + let svg = await renderCard(axiosRes.data, params); + res.status(200).send(svg as any); } diff --git a/pages/index.tsx b/pages/index.tsx index 105b1a2..52ee44a 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,119 +1,187 @@ -import Head from 'next/head' -import styled from 'styled-components'; -import { useState } from 'react'; +import Head from "next/head"; +import styled, { createGlobalStyle, GlobalStyleComponent } from "styled-components"; +import { useState } from "react"; export default function Home() { - const [userId, setUserId] = useState(':id') + const [userId, setUserId] = useState(null); + const [copyState, setCopyState] = useState("Copy"); + const copy = () => { + navigator.clipboard.writeText(`[![Discord Presence](https://lanyard-profile-readme.vercel.app/api/${userId} + )](https://discord.com/users/${userId})`); + setCopyState("Copied!"); + + setTimeout(() => setCopyState("Copy"), 1500); + }; return ( <> + - + Lanyard for GitHub Profile + + + - - -
- 🏷️ lanyard-profile-readme -
+
-

Make sure you're in the Discord for this to work.

- setUserId(e.target.value))} /> - Copy the following and paste it into your README.md - - [![Discord Presence](https://lanyard-profile-readme.vercel.app/api/{userId})](https://discord.com/users/{userId}) - - For further customization, check out the repo! - + 🏷️ + lanyard profile readme + Utilize Lanyard to display your Discord Presence in your GitHub Profile +
+ setUserId(el.target.value)} placeholder="Enter your Discord ID" /> + {userId ? ( + <> + + [![Discord Presence](https://lanyard-profile-readme.vercel.app/api/{userId} + )](https://discord.com/users/{userId}) + + {copyState} + + + ) : null}
- +
- ) + ); } -const Background = styled.div` - position: fixed; - width: 100%; - height: 100%; +const GlobalStyle = createGlobalStyle` + *, *::before, *::after { + box-sizing: border-box; margin: 0; - inset: 0; - background: url(/background.png) 60% 50%; - background-size: cover; - color: #fff; - font-size: 20px; - font-family: Poppins, sans-serif; + padding: 0; + font-family: 'Poppins', sans-serif; + } + ::-webkit-scrollbar { + width: 10px; + } + + ::-webkit-scrollbar-thumb { + background: rgb(64 68 78); + border-radius: 8px; + } + + ::-webkit-scrollbar-track { + background: rgb(24 28 39); + } +`; + +const Main = styled.div` display: flex; - flex-direction: column; - justify-content: center; align-items: center; -` - -const Header = styled.h1` - font-size: 2rem; - text-align: center; - width: 100%; - white-space: nowrap; -` + justify-content: center; + margin: 0; + padding: 0; + box-sizing: border-box; + max-width: 100vw; + min-height: 100vh; + background: url(./background.jpg) 50% no-repeat fixed; + background-size: cover; +`; const Container = styled.div` - min-width: 300px; - width: 40%; - height: auto; - padding: 2rem; + backdrop-filter: blur(50px); + background: rgb(0, 0, 0, 0.18); + border-radius: 10px; + margin: 50px; + padding: 10px; + width: 80%; + max-width: 500px; +`; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; +const Icon = styled.h1` + font-size: 2.5em; + position: absolute; + top: -27px; + left: -21px; +`; - background-color: rgba(0, 0, 0, 0.3); - backdrop-filter: blur(7px); +const Title = styled.h1` + text-align: left; + font-size: 2.25em; + font-weight: 600; + margin: 5px 25px; + color: #cecece; +`; - text-align: center; - border: solid 0.5px #fff; - border-radius: 0.5rem; - margin-bottom: 1rem; -` +const Paragraph = styled.p` + padding: 0 25px; + color: #aaabaf; + font-size: 1.12em; +`; const Input = styled.input` - margin: 10px 0 20px 0; - width: 60%; - border: solid 2px #ccc; - font-size: 1.1rem; - border-radius: 3px; - text-align: center; - padding: 10px; - background: rgba(0, 0, 0, 0.5); - color: #fff; + text-align: left; + border-radius: 8px; + border: none; + margin: 0 25px 15px; + font-size: 1em; + padding: 5px 10px; + color: #aaabaf; + background: #191d28; + box-shadow: 0px 3px 15px rgba(0, 0, 0, 0.2); + transition: background ease-in-out 0.2s; - &::placeholder { - text-align: center; + &:focus { + outline: 0; + background: #11151f; } -` +`; -const Link = styled.div` - margin: 10px 0 20px 0; - width: calc(100% - 40px); - height: auto; - font-size: 1.1rem; - border: solid 1px #ccc; - border-radius: 3px; - padding: 5px; - background-color: #222; +const Output = styled.div` + margin: 15px 25px; + color: #aaabaf; + word-break: break-word; + border-radius: 8px; + padding: 8px; + backdrop-filter: blur(50px); + background: rgb(0, 0, 0, 0.1); + box-shadow: 0px 3px 15px rgba(0, 0, 0, 0.2); +`; - scrollbar-width: thin; -` +const Copy = styled.button` + position: absolute; + right: 35px; + font-size: 0.9em; + padding: 5px 25px; + width: 103px; + border-radius: 6px; + cursor: pointer; + border: none; + color: #aaabaf; + backdrop-filter: blur(50px); + box-shadow: 0px 3px 15px rgba(0, 0, 0, 0.2); + background: #191d28; + transition: background ease-in-out 0.2s; + + &:hover { + background: #11151f; + } + &:active { + background: #0c0d13; + } +`; const Example = styled.img` - margin-top: 1.5rem; - - @media(max-height: 800px){ - display: none; - } - - @media(max-width: 1000px){ - display: none; - } -` \ No newline at end of file + display: block; + margin: 70px auto 0px; + padding: 0 20px 15px; + width: 100%; + filter: drop-shadow(0px 3px 15px rgba(0, 0, 0, 0.2)); +`; diff --git a/public/background.jpg b/public/background.jpg new file mode 100644 index 0000000..3cf890e Binary files /dev/null and b/public/background.jpg differ diff --git a/public/background.png b/public/background.png deleted file mode 100644 index e5b1df5..0000000 Binary files a/public/background.png and /dev/null differ diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 4965832..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/favicon/android-chrome-192x192.png b/public/favicon/android-chrome-192x192.png new file mode 100644 index 0000000..600ea2b Binary files /dev/null and b/public/favicon/android-chrome-192x192.png differ diff --git a/public/favicon/android-chrome-512x512.png b/public/favicon/android-chrome-512x512.png new file mode 100644 index 0000000..fb0b7d5 Binary files /dev/null and b/public/favicon/android-chrome-512x512.png differ diff --git a/public/favicon/apple-touch-icon.png b/public/favicon/apple-touch-icon.png new file mode 100644 index 0000000..e3d5e8b Binary files /dev/null and b/public/favicon/apple-touch-icon.png differ diff --git a/public/favicon/favicon-16x16.png b/public/favicon/favicon-16x16.png new file mode 100644 index 0000000..300b7e1 Binary files /dev/null and b/public/favicon/favicon-16x16.png differ diff --git a/public/favicon/favicon-32x32.png b/public/favicon/favicon-32x32.png new file mode 100644 index 0000000..18f1589 Binary files /dev/null and b/public/favicon/favicon-32x32.png differ diff --git a/public/favicon/mstile-144x144.png b/public/favicon/mstile-144x144.png new file mode 100644 index 0000000..258c9b5 Binary files /dev/null and b/public/favicon/mstile-144x144.png differ diff --git a/public/favicon/mstile-150x150.png b/public/favicon/mstile-150x150.png new file mode 100644 index 0000000..a6fe5f8 Binary files /dev/null and b/public/favicon/mstile-150x150.png differ diff --git a/public/favicon/mstile-310x150.png b/public/favicon/mstile-310x150.png new file mode 100644 index 0000000..93370d0 Binary files /dev/null and b/public/favicon/mstile-310x150.png differ diff --git a/public/favicon/mstile-310x310.png b/public/favicon/mstile-310x310.png new file mode 100644 index 0000000..5ee31b1 Binary files /dev/null and b/public/favicon/mstile-310x310.png differ diff --git a/public/favicon/mstile-70x70.png b/public/favicon/mstile-70x70.png new file mode 100644 index 0000000..68381b9 Binary files /dev/null and b/public/favicon/mstile-70x70.png differ diff --git a/public/favicon/safari-pinned-tab.svg b/public/favicon/safari-pinned-tab.svg new file mode 100644 index 0000000..b615a7e --- /dev/null +++ b/public/favicon/safari-pinned-tab.svg @@ -0,0 +1,26 @@ + + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + diff --git a/src/LanyardTypes.ts b/src/LanyardTypes.ts index 674a604..c932646 100644 --- a/src/LanyardTypes.ts +++ b/src/LanyardTypes.ts @@ -75,4 +75,4 @@ export interface Assets { small_image?: string; large_text: string; large_image: string; -} \ No newline at end of file +} diff --git a/src/getFlags.ts b/src/getFlags.ts index 77b749f..36a9674 100644 --- a/src/getFlags.ts +++ b/src/getFlags.ts @@ -1,16 +1,16 @@ export const getFlags = (flag: number): string[] => { let flags: string[] = []; - if (flag & 1) flags.push("Discord_Employee") - if (flag & 2) flags.push("Partnered_Server_Owner") - if (flag & 4) flags.push("HypeSquad_Events") - if (flag & 8) flags.push("Bug_Hunter_Level_1") - if (flag & 64) flags.push("House_Bravery") - if (flag & 128) flags.push("House_Brilliance") - if (flag & 256) flags.push("House_Balance") - if (flag & 512) flags.push("Early_Supporter") - if (flag & 16384) flags.push("Bug_Hunter_Level_2") - if (flag & 131072) flags.push("Early_Verified_Bot_Developer") + if (flag & 1) flags.push("Discord_Employee"); + if (flag & 2) flags.push("Partnered_Server_Owner"); + if (flag & 4) flags.push("HypeSquad_Events"); + if (flag & 8) flags.push("Bug_Hunter_Level_1"); + if (flag & 64) flags.push("House_Bravery"); + if (flag & 128) flags.push("House_Brilliance"); + if (flag & 256) flags.push("House_Balance"); + if (flag & 512) flags.push("Early_Supporter"); + if (flag & 16384) flags.push("Bug_Hunter_Level_2"); + if (flag & 131072) flags.push("Early_Verified_Bot_Developer"); return flags; -} \ No newline at end of file +}; diff --git a/src/renderCard.tsx b/src/renderCard.tsx index 6ba7f9f..f3f5b99 100644 --- a/src/renderCard.tsx +++ b/src/renderCard.tsx @@ -1,9 +1,9 @@ //probably the messiest code i've ever written but it works so :) -import { Badges } from '../public/assets/badges/BadgesEncoded'; -import { getFlags } from './getFlags'; -import * as LanyardTypes from './LanyardTypes'; -import { encodeBase64 } from './toBase64'; +import { Badges } from "../public/assets/badges/BadgesEncoded"; +import { getFlags } from "./getFlags"; +import * as LanyardTypes from "./LanyardTypes"; +import { encodeBase64 } from "./toBase64"; type Parameters = { theme?: string; @@ -12,31 +12,36 @@ type Parameters = { hideDiscrim?: string; hideStatus?: string; borderRadius?: string; -} +}; const renderCard = async (body: LanyardTypes.Root, params: Parameters): Promise => { - const defaultAvatar: string = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAMAAABrrFhUAAAAY1BMVEVYZfJib/OMlfahqPeWn/eBi/XLz/vq6/7////19f5tePTq7P22vPnV2Pyrsvirsvl3gvT09f7Axfp3gfRtePNsePPg4v22vPq2u/qCi/WhqPjf4/zf4v2Xn/essvjLzvuXnvdbidFTAAAETElEQVR4AezBgQAAAACAoP2pF6kCAAAAAAAAAAAAAAAAAAAAAIDZudMtV1UlDuCFRKlWIEJ6uOwbzXn/lzzzYc/GWiT6zya/79WrLeYSc5Vq9IFWa3Sr6JehWt0ZZn5RtFJvmHnodPsrPLx1/B9PKx1ziLOPnIRRO84EXaAP/CWnR3pArTWcybpA5G8NsX20pw+cSbpAngEeOQenY+Cf8KIZ4FuDfSV4Ko/7hS7wNjYH7W3MvNeHtn2jvxn+OXcgaP0x8KJo43vgnwqu85EXDfGVULWON9G1BOmDN/M/AnTgDSWC0xve0KAITeSsykFw4qzOQWB4YwNBOfLmPAHpeXsvr5XOgJkjGA3vIlU6A2bvOHvAnXwiCMrwTl5UpUtg5us7BAB2gcg78nXugaC6QORd+bo7AEAXiLwzX+8SANEFNHPdXcAwV90FDgxA037+zwAc7aZlCKnSNTDrADZBdU6DBwbha5wCAabBkWGkSqfAzFa6C8xeADYB9Y2ByEBsbSMAYAy0zHWPActQLPQuKBh3DiwiDRlwzwFOv9JfTpORh5x5rVfQc8CQiLLJiEMaA1oW6XgVq+grVh4yY56JA68x07fm8hCIhXCUPn823zgkG/HK4Rf6kYv8YBt5BQ03BQyv9CMq8M/JQ7IItw+e6cd8QQjKTqCX3OMTtOdCCNZOoCnqkrYgZEFD2/FF/08qDAE4Dji+TtHPKHknVmBboVB2i9HI9zIGahZUhaVqVxCyQEEVQ7rSBMj3QiPUUTCWJkC+8zrQVjzmELBYG2H5jDYUFqAiQDlMtAwKQgjr+nwoq9O2BSEQJQFVWKeNBSEQ6+BYeG3BFIUAHIfasmsLh7IQgLcjDZd0AWXEIZRDMDYCuuj73g95yJGxEuBLPmr6VBSyzMO9Fpzko3kqeA1r8W4GHOWNKQ/JIl4COL4SZf2lPAQhAY4lYrv860rlIVmHlYAsuBhjFwpCwO4LOkb0TMAzAc8EPBPwTMAGngl4JuCZgMig4jMB27AMykJUhCr4ekwzKI10T9hpwzcz6DNSUbRdORzThW/CJSKagd4LjKurof1suFCYVR54MDckpsBXDLk3pliQgxBTHneBrwiaNtOfeUUKCnMQYlKC32x2r7SlmSUpoOQdi5xtoqx1DNP8WW9kKSCVvAu8QnC2USR4/I2bP5vDmhS80pdOjXULw8dc7HSiL6ljYLTmz/ooKvJTdkqTt9G5s/mHczH6qXlV9I32Ehi0+QVfQbn7HryHhvY033V1Tuu3CRncOIj3rL3EV9pf7+53ced0bY+MIZm7ndEt9uNnkxN8OSWhAvjjZ8ktnIoKaMDHF0yH8S416C4Rpv7bU094pWJ9QFv4BJOBvnkFzjWKMvhu4G78IibMIz2EFM3KFUAwCEI+ID9MDia6kd/+enpFj+YE+af+aA8OZAAAAAAG+Vvf46sAAAAAAAAAAAAAAAAAAAAAAFYCeHSjWah9hFcAAAAASUVORK5CYII="; + const defaultAvatar: string = + "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAMAAABrrFhUAAAAY1BMVEVYZfJib/OMlfahqPeWn/eBi/XLz/vq6/7////19f5tePTq7P22vPnV2Pyrsvirsvl3gvT09f7Axfp3gfRtePNsePPg4v22vPq2u/qCi/WhqPjf4/zf4v2Xn/essvjLzvuXnvdbidFTAAAETElEQVR4AezBgQAAAACAoP2pF6kCAAAAAAAAAAAAAAAAAAAAAIDZudMtV1UlDuCFRKlWIEJ6uOwbzXn/lzzzYc/GWiT6zya/79WrLeYSc5Vq9IFWa3Sr6JehWt0ZZn5RtFJvmHnodPsrPLx1/B9PKx1ziLOPnIRRO84EXaAP/CWnR3pArTWcybpA5G8NsX20pw+cSbpAngEeOQenY+Cf8KIZ4FuDfSV4Ko/7hS7wNjYH7W3MvNeHtn2jvxn+OXcgaP0x8KJo43vgnwqu85EXDfGVULWON9G1BOmDN/M/AnTgDSWC0xve0KAITeSsykFw4qzOQWB4YwNBOfLmPAHpeXsvr5XOgJkjGA3vIlU6A2bvOHvAnXwiCMrwTl5UpUtg5us7BAB2gcg78nXugaC6QORd+bo7AEAXiLwzX+8SANEFNHPdXcAwV90FDgxA037+zwAc7aZlCKnSNTDrADZBdU6DBwbha5wCAabBkWGkSqfAzFa6C8xeADYB9Y2ByEBsbSMAYAy0zHWPActQLPQuKBh3DiwiDRlwzwFOv9JfTpORh5x5rVfQc8CQiLLJiEMaA1oW6XgVq+grVh4yY56JA68x07fm8hCIhXCUPn823zgkG/HK4Rf6kYv8YBt5BQ03BQyv9CMq8M/JQ7IItw+e6cd8QQjKTqCX3OMTtOdCCNZOoCnqkrYgZEFD2/FF/08qDAE4Dji+TtHPKHknVmBboVB2i9HI9zIGahZUhaVqVxCyQEEVQ7rSBMj3QiPUUTCWJkC+8zrQVjzmELBYG2H5jDYUFqAiQDlMtAwKQgjr+nwoq9O2BSEQJQFVWKeNBSEQ6+BYeG3BFIUAHIfasmsLh7IQgLcjDZd0AWXEIZRDMDYCuuj73g95yJGxEuBLPmr6VBSyzMO9Fpzko3kqeA1r8W4GHOWNKQ/JIl4COL4SZf2lPAQhAY4lYrv860rlIVmHlYAsuBhjFwpCwO4LOkb0TMAzAc8EPBPwTMAGngl4JuCZgMig4jMB27AMykJUhCr4ekwzKI10T9hpwzcz6DNSUbRdORzThW/CJSKagd4LjKurof1suFCYVR54MDckpsBXDLk3pliQgxBTHneBrwiaNtOfeUUKCnMQYlKC32x2r7SlmSUpoOQdi5xtoqx1DNP8WW9kKSCVvAu8QnC2USR4/I2bP5vDmhS80pdOjXULw8dc7HSiL6ljYLTmz/ooKvJTdkqTt9G5s/mHczH6qXlV9I32Ehi0+QVfQbn7HryHhvY033V1Tuu3CRncOIj3rL3EV9pf7+53ced0bY+MIZm7ndEt9uNnkxN8OSWhAvjjZ8ktnIoKaMDHF0yH8S416C4Rpv7bU094pWJ9QFv4BJOBvnkFzjWKMvhu4G78IibMIz2EFM3KFUAwCEI+ID9MDia6kd/+enpFj+YE+af+aA8OZAAAAAAG+Vvf46sAAAAAAAAAAAAAAAAAAAAAAFYCeHSjWah9hFcAAAAASUVORK5CYII="; let avatarBorderColor: string = "#747F8D", userStatus: string = "", avatarExtension: string = "webp", statusExtension: string = "webp", activity: any = false, - backgroundColor: string = '1a1c1f', - theme = 'dark', - discrim = 'show', - hideStatus = 'false', - borderRadius = '10px'; + backgroundColor: string = "1a1c1f", + theme = "dark", + discrim = "show", + hideStatus = "false", + borderRadius = "10px"; if (body.data.activities[0]?.emoji?.animated) statusExtension = "gif"; if (body.data.discord_user.avatar && body.data.discord_user.avatar.startsWith("a_")) avatarExtension = "gif"; - if (body.data.activities.length > 0 && body.data.activities[Object.keys(body.data.activities).length - 1].type === 0) activity = body.data.activities[Object.keys(body.data.activities).length - 1]; + if ( + body.data.activities.length > 0 && + body.data.activities[Object.keys(body.data.activities).length - 1].type === 0 + ) + activity = body.data.activities[Object.keys(body.data.activities).length - 1]; if (params.animated === "false") avatarExtension = "webp"; - if (params.hideStatus === 'true') hideStatus = 'true'; + if (params.hideStatus === "true") hideStatus = "true"; if (params.hideDiscrim === "true") discrim = "hide"; - if (params.theme === 'light') { - backgroundColor = '#eee'; - theme = 'light'; + if (params.theme === "light") { + backgroundColor = "#eee"; + theme = "light"; } if (params.bg) backgroundColor = params.bg; if (params.borderRadius) borderRadius = params.borderRadius; @@ -58,9 +63,8 @@ const renderCard = async (body: LanyardTypes.Root, params: Parameters): Promise< const flags: string[] = getFlags(body.data.discord_user.public_flags); - if (body.data.activities[0] && body.data.activities[0].state && body.data.activities[0].type === 4) userStatus = body.data.activities[0].state; - - console.log(Object.keys(body.data.activities).length); + if (body.data.activities[0] && body.data.activities[0].state && body.data.activities[0].type === 4) + userStatus = body.data.activities[0].state; return ` @@ -71,7 +75,7 @@ const renderCard = async (body: LanyardTypes.Root, params: Parameters): Promise< height: 200px; inset: 0; background-color: #${backgroundColor}; - color: ${theme === 'dark' ? '#fff' : '#000'}; + color: ${theme === "dark" ? "#fff" : "#000"}; font-family: 'Century Gothic', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; font-size: 16px; display: flex; @@ -86,7 +90,9 @@ const renderCard = async (body: LanyardTypes.Root, params: Parameters): Promise< display: flex; flex-direction: row; padding-bottom: 5px; - border-bottom: solid 0.5px ${theme === 'dark' ? 'hsl(0, 0%, 100%, 10%)' : 'hsl(0, 0%, 0%, 10%)'}; + border-bottom: solid 0.5px ${ + theme === "dark" ? "hsl(0, 0%, 100%, 10%)" : "hsl(0, 0%, 0%, 10%)" + }; ">
- - ${body.data.discord_user.username}${discrim !== 'hide' ? `#${body.data.discord_user.discriminator}` : ''} + ${body.data.discord_user.username}${ + discrim !== "hide" + ? `#${ + body.data.discord_user.discriminator + }` + : "" + } - ${flags.map((v) => ` + ${flags + .map( + v => ` `).join('')} + " />` + ) + .join("")}
- ${userStatus.length > 0 && hideStatus !== "true" ? ` + ${ + userStatus.length > 0 && hideStatus !== "true" + ? `

- ${body.data.activities[0].emoji && body.data.activities[0].emoji.id ? ` - `: ``} - ${body.data.activities[0].emoji && !body.data.activities[0].emoji.id ? body.data.activities[0].emoji.name + ' ' + userStatus.replace(/\&/g, "and") : userStatus.replace(/\&/g, "and")} -

` : ``} + " />` + : `` + } + ${ + body.data.activities[0].emoji && !body.data.activities[0].emoji.id + ? body.data.activities[0].emoji.name + + " " + + userStatus.replace(/\&/g, "and") + : userStatus.replace(/\&/g, "and") + } + ` + : `` + } - ${activity ? ` + ${ + activity + ? `
- ${activity.assets && activity.assets.large_image ? ` - - ` : ` - - `} - ${activity.assets && activity.assets.small_image ? ` - `: ``} + "/>` + : `` + }
-

PLAYING A GAME...

+

PLAYING A GAME...

${activity.name}

- ${activity.details ? ` + ${ + activity.details + ? `

${activity.details}

` : ``} + ">${activity.details}

` + : `` + }
- `: ``} + ` + : `` + } - ${body.data.listening_to_spotify === true && body.data.activities[Object.keys(body.data.activities).length - 1].type === 2 ? ` + ${ + body.data.listening_to_spotify === true && + body.data.activities[Object.keys(body.data.activities).length - 1].type === 2 + ? `
-

LISTENING NOW...

+

LISTENING NOW...

By ${body.data.spotify.artist.replace(/\;/g, ",").replace(/\&/g, "and")}

- ` : ``} - ${!activity && body.data.listening_to_spotify === false ? - `
I'm not currently doing anything!

` - : ``} + : `` + } `; -} +}; export default renderCard; diff --git a/src/snowflake.ts b/src/snowflake.ts index 6aa2359..480fe0a 100644 --- a/src/snowflake.ts +++ b/src/snowflake.ts @@ -1,44 +1,9 @@ -interface DeconstructedSnowflake { - timestamp: number; - date: Date; - workerID: number; - processID: number; - increment: number; - binary: string; -} - const EPOCH = 1420070400000; // Discord's EPOCH -export function isSnowflake(snowflake: string): boolean { - const { timestamp } = deconstruct(snowflake); - return (timestamp > EPOCH && timestamp <= 3619093655551); -} - -function deconstruct(snowflake: string): DeconstructedSnowflake { - const BINARY = idToBinary(snowflake).padStart(64, "0"); - return { - timestamp: parseInt(BINARY.substring(0, 42), 2) + EPOCH, - get date() { - return new Date(this.timestamp); - }, - workerID: parseInt(BINARY.substring(42, 47), 2), - processID: parseInt(BINARY.substring(47, 52), 2), - increment: parseInt(BINARY.substring(52, 64), 2), - binary: BINARY, - }; -} - -function idToBinary(snowflake: string): string { - let bin = ""; - let high = parseInt(snowflake.slice(0, -10)) || 0; - let low = parseInt(snowflake.slice(-10)); - while (low > 0 || high > 0) { - bin = String(low & 1) + bin; - low = Math.floor(low / 2); - if (high > 0) { - low += 5000000000 * (high % 2); - high = Math.floor(high / 2); - } - } - return bin; +// Snowflakes will never be a string +export function isSnowflake(snowflake: number | string): boolean { + snowflake = Number(snowflake); + return ( + Number.isInteger(+snowflake) && snowflake > 4194304 && !isNaN(new Date(snowflake / 4194304 + EPOCH).getTime()) + ); } diff --git a/src/toBase64.ts b/src/toBase64.ts index cf7d98c..265c634 100644 --- a/src/toBase64.ts +++ b/src/toBase64.ts @@ -6,8 +6,8 @@ export const encodeBase64 = async (url: string): Promise => { try { response = await imageToBase64(url); } catch (e) { - console.log(e) + console.log(e); } return response; -} \ No newline at end of file +}; diff --git a/yarn.lock b/yarn.lock index c71d69f..a719565 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2553,6 +2553,11 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +prettier@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6" + integrity sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA== + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"