Add the Fediverse Info
This commit is contained in:
parent
12e68cb2a7
commit
51091d6d59
7 changed files with 155 additions and 19 deletions
|
@ -20,10 +20,11 @@ This package uses [`@carbon/icons-react`](https://github.com/carbon-design-syste
|
|||
netlify env:set IBM_TELEMETRY_DISABLED true
|
||||
```
|
||||
|
||||
This package makes use of several online APIs through Netlify in order to deliver the `Infos` that are available on the right side of the website for large screens, accessing most of these APIs requires a key (or similar), which can be set through the following environment variables:
|
||||
This package makes use of several online APIs through Netlify in order to deliver the `Infos` that are available on the right side of the website, accessing most of these APIs requires a key (or similar), which can be set through the following environment variables:
|
||||
|
||||
- `API_GITHUB`
|
||||
- `API_GITLAB`
|
||||
- `API_KITSUCLUB`
|
||||
- `API_LASTFM`
|
||||
- `API_OSU`
|
||||
- `API_WANIKANI`
|
||||
|
|
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
42
netlify/functions/kitsuclub.ts
Normal file
42
netlify/functions/kitsuclub.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import {type Handler} from "@netlify/functions";
|
||||
import { KitsuclubInfo } from "../../src/components/Info/Fediverse/KitsuClub.js";
|
||||
|
||||
const handler: Handler = async () => {
|
||||
const kitsuclub = await fetch("https://kitsunes.club/api/users/notes", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Authorization": `Bearer ${process.env.API_KITSUCLUB}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
"userId": "a2hgd7delf",
|
||||
"limit": 1,
|
||||
"withReplies": false,
|
||||
"withRepliesToSelf": false,
|
||||
"withQuotes": true,
|
||||
"withRenotes": false,
|
||||
"withBots": true,
|
||||
"withNonPublic": true,
|
||||
"withChannelNotes": false,
|
||||
"withFiles": false,
|
||||
"allowPartial": false,
|
||||
})
|
||||
});
|
||||
|
||||
const details = (await kitsuclub.json() as Record<string, any>)[0];
|
||||
const activity: KitsuclubInfo = {
|
||||
id: details.user.username,
|
||||
username: details.user.name,
|
||||
avatar: details.user.avatarUrl,
|
||||
emojis: details.user.emojis,
|
||||
text: details.text,
|
||||
date: details.createdAt
|
||||
}
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify(activity),
|
||||
};
|
||||
};
|
||||
|
||||
export {handler};
|
34
package.json
34
package.json
|
@ -7,34 +7,34 @@
|
|||
"lint:fix": "bunx eslint . --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@carbon/icons-react": "^11.52.0",
|
||||
"@carbon/icons-react": "^11.53.0",
|
||||
"@netlify/functions": "^2.8.2",
|
||||
"@octokit/rest": "^20.1.1",
|
||||
"mongodb": "^6.10.0",
|
||||
"mongodb": "^6.12.0",
|
||||
"osu-api-v2-js": "^1.1.0",
|
||||
"react": "^19.0.0-rc-fb9a90fa48-20240614",
|
||||
"react-dom": "^19.0.0-rc-fb9a90fa48-20240614",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"timeago.js": "^4.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.1.0",
|
||||
"@eslint/js": "^9.13.0",
|
||||
"@stylistic/eslint-plugin-ts": "^2.9.0",
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
"@types/node": "^20.17.3",
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
"@eslint/js": "^9.18.0",
|
||||
"@stylistic/eslint-plugin-ts": "^2.13.0",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@types/node": "^20.17.13",
|
||||
"@types/react": "npm:types-react@beta",
|
||||
"@types/react-dom": "npm:types-react-dom@beta",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^9.13.0",
|
||||
"eslint": "^9.18.0",
|
||||
"eslint-config-xo-typescript": "^7.0.0",
|
||||
"eslint-plugin-react": "^7.37.2",
|
||||
"postcss": "^8.4.47",
|
||||
"eslint-plugin-react": "^7.37.4",
|
||||
"postcss": "^8.5.1",
|
||||
"react-animate-height": "^3.2.3",
|
||||
"tailwindcss": "^3.4.14",
|
||||
"typescript": "^5.6.3",
|
||||
"typescript-eslint": "^8.12.2",
|
||||
"vite": "^5.4.10"
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.7.3",
|
||||
"typescript-eslint": "^8.20.0",
|
||||
"vite": "^5.4.11"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
|
|
16
src/components/Info/Fediverse.tsx
Normal file
16
src/components/Info/Fediverse.tsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
import React from "react";
|
||||
import Info from "../Info.js";
|
||||
import KitsuClub from "./Fediverse/KitsuClub.js";
|
||||
|
||||
export default function Hacking() {
|
||||
const kitsuclub = <KitsuClub key={"kitsuclub"}/>;
|
||||
|
||||
return (
|
||||
<Info
|
||||
type="Fediverse"
|
||||
websites={[
|
||||
kitsuclub,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
75
src/components/Info/Fediverse/KitsuClub.tsx
Normal file
75
src/components/Info/Fediverse/KitsuClub.tsx
Normal file
|
@ -0,0 +1,75 @@
|
|||
import React, {useState, useEffect} from "react";
|
||||
import Website from "../../Website.js";
|
||||
|
||||
export type KitsuclubInfo = {
|
||||
id: string
|
||||
username: string
|
||||
avatar: string
|
||||
emojis: Record<string, string>
|
||||
text: string
|
||||
date: string
|
||||
} | undefined;
|
||||
|
||||
export default function KitsuClub() {
|
||||
const [kitsuclub, setKitsuclub]: [KitsuclubInfo, React.Dispatch<React.SetStateAction<KitsuclubInfo>>] = useState();
|
||||
const [elements, setElements] = useState([] as React.JSX.Element[]);
|
||||
const [error, setError] = useState(false);
|
||||
|
||||
const getKitsuclub = async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
setKitsuclub(await fetch("/.netlify/functions/kitsuclub").then(async r => r.json()));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getKitsuclub().catch(() => {
|
||||
setError(true);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (kitsuclub) {
|
||||
const date = new Date(kitsuclub.date).toISOString()
|
||||
try {
|
||||
setElements([
|
||||
<div key={"kitsuclub-details"} className="text-left mb-2">
|
||||
<img key={"kitsuclub-avatar"} src={kitsuclub.avatar} alt="avatar" className="float-left rounded-lg w-12 mr-2"/>
|
||||
<strong key={"kitsuclub-username"} className="inline-flex">{...emojify(kitsuclub.username, kitsuclub.emojis)}</strong>
|
||||
<br/>
|
||||
<strong key={"kitsuclub-date"} className="inline-flex text-sm">{date.substring(0, date.indexOf("T"))}</strong>
|
||||
</div>,
|
||||
<p key={"kitsuclub-text"} className="text-left">{...emojify(kitsuclub.text, kitsuclub.emojis)}</p>, // emojis that are only in the post aren't in the response yet :(
|
||||
])
|
||||
} catch {
|
||||
setError(true)
|
||||
}
|
||||
}
|
||||
}, [kitsuclub]);
|
||||
|
||||
return (
|
||||
<Website
|
||||
name="KitsuClub"
|
||||
link={`https://kitsunes.club/@${kitsuclub?.id ?? "taevas"}`}
|
||||
elements={elements}
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function emojify(text: string, all_emojis: Record<string, string>): Array<string | React.JSX.Element> {
|
||||
const emoji_list: string[] = Object.keys(all_emojis)
|
||||
const emoji_imgs: string[] = Object.values(all_emojis)
|
||||
const to_return: Array<string | React.JSX.Element> = []
|
||||
|
||||
for (let i = 0; i < emoji_list.length; i++) {
|
||||
const emoji_name = emoji_list[i]
|
||||
while (text.indexOf(emoji_name) !== -1) {
|
||||
const index = text.indexOf(emoji_name)
|
||||
to_return.push(text.substring(0, index - 1)) // push whatever text before the emoji
|
||||
to_return.push(<img src={emoji_imgs[i]} alt={emoji_name} className="h-6 w-6 mx-1"/>) // push the emoji
|
||||
text = text.substring(index + emoji_name.length + 1) // remove whatever text before the emoji and the emoji name
|
||||
}
|
||||
}
|
||||
to_return.push(text) // push whatever text AFTER the last emoji (so all the text if no emoji)
|
||||
|
||||
return to_return
|
||||
}
|
|
@ -6,6 +6,7 @@ import Coding from "../components/Info/Coding.js";
|
|||
import RhythmGames from "../components/Info/RhythmGames.js";
|
||||
import Anime from "../components/Info/Anime.js";
|
||||
// import Japanese from "../components/Info/Japanese.js";
|
||||
import Fediverse from "../components/Info/Fediverse.js"
|
||||
|
||||
export default class Infos extends Component {
|
||||
private readonly dragbar = React.createRef<HTMLDivElement>();
|
||||
|
@ -17,10 +18,11 @@ export default class Infos extends Component {
|
|||
<div draggable="false" ref={this.dragbar} className="z-[100] h-full w-[25px] fixed right-[7px] lg:right-[340px] cursor-ew-resize select-none hover:bg-gradient-to-r from-white/80 to-white/1 active:to-white/20"></div>
|
||||
<div className="z-[90] p-2.5 flex flex-wrap text-white">
|
||||
<Music/>
|
||||
<Fediverse/>
|
||||
<Coding/>
|
||||
<Speedrun/>
|
||||
<Anime/>
|
||||
{/* <Japanese/> */}
|
||||
{/*<Japanese/>*/}
|
||||
<RhythmGames/>
|
||||
<Hacking/>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue