✨ addeds embeds for profiles
This commit is contained in:
parent
c90a4c141e
commit
5b5e21e614
9 changed files with 1006 additions and 896 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -4,5 +4,6 @@
|
|||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": "explicit",
|
||||
"source.organizeImports": "explicit"
|
||||
}
|
||||
},
|
||||
"typescript.tsdk": "node_modules\\typescript\\lib"
|
||||
}
|
||||
|
|
|
|||
893
.yarn/releases/yarn-4.1.1.cjs
vendored
893
.yarn/releases/yarn-4.1.1.cjs
vendored
File diff suppressed because one or more lines are too long
925
.yarn/releases/yarn-4.5.0.cjs
vendored
Normal file
925
.yarn/releases/yarn-4.5.0.cjs
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
yarnPath: .yarn/releases/yarn-4.1.1.cjs
|
||||
yarnPath: .yarn/releases/yarn-4.5.0.cjs
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "fixbluesky",
|
||||
"private": true,
|
||||
"packageManager": "yarn@4.1.1",
|
||||
"packageManager": "yarn@4.5.0",
|
||||
"volta": {
|
||||
"node": "21.7.3",
|
||||
"yarn": "4.1.1"
|
||||
|
|
|
|||
31
src/components/Profile.tsx
Normal file
31
src/components/Profile.tsx
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { AppBskyActorDefs } from "@atproto/api";
|
||||
|
||||
import { OEmbedTypes } from "../routes/getOEmbed.ts";
|
||||
import { Layout } from "./Layout.tsx";
|
||||
|
||||
interface ProfileProps {
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed;
|
||||
url: string;
|
||||
appDomain: string;
|
||||
}
|
||||
|
||||
export const Profile = ({ profile, url, appDomain }: ProfileProps) => (
|
||||
<Layout url={url}>
|
||||
<meta name="twitter:creator" content={`@${profile.handle}`} />
|
||||
<meta property="og:description" content={profile.description ?? ""} />
|
||||
<meta
|
||||
property="og:title"
|
||||
content={`${profile.displayName} (@${profile.handle})`}
|
||||
/>
|
||||
<meta property="og:image" content={profile.avatar} />
|
||||
|
||||
<link
|
||||
type="application/json+oembed"
|
||||
href={`https://${appDomain}/oembed?type=${OEmbedTypes.Profile}&follows=${
|
||||
profile.followsCount
|
||||
}&posts=${profile.postsCount}&avatar=${encodeURIComponent(
|
||||
profile.avatar ?? ""
|
||||
)}`}
|
||||
/>
|
||||
</Layout>
|
||||
);
|
||||
14
src/lib/fetchProfile.ts
Normal file
14
src/lib/fetchProfile.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { BskyAgent } from "@atproto/api";
|
||||
|
||||
export interface fetchProfileOptions {
|
||||
user: string;
|
||||
}
|
||||
|
||||
export async function fetchProfile(
|
||||
agent: BskyAgent,
|
||||
{ user }: fetchProfileOptions
|
||||
) {
|
||||
return agent.getProfile({
|
||||
actor: user,
|
||||
});
|
||||
}
|
||||
|
|
@ -5,7 +5,9 @@ import { serve } from "@hono/node-server";
|
|||
import { Hono } from "hono";
|
||||
import { HTTPException } from "hono/http-exception";
|
||||
import { Redis } from "ioredis";
|
||||
import { getOEmbed } from "./routes/getOEmbed.ts";
|
||||
import { getPost } from "./routes/getPost.tsx";
|
||||
import { getProfile } from "./routes/getProfile.tsx";
|
||||
|
||||
// biome-ignore lint/style/noNonNullAssertion: check is ran at app start
|
||||
const redis = new Redis(6379, process.env.REDIS_HOSTNAME!);
|
||||
|
|
@ -58,6 +60,11 @@ app.use("*", async (c, next) => {
|
|||
app.get("/profile/:user/post/:post", getPost);
|
||||
app.get("/https://bsky.app/profile/:user/post/:post", getPost);
|
||||
|
||||
app.get("/profile/:user", getProfile);
|
||||
app.get("/https://bsky.app/profile/:user", getProfile);
|
||||
|
||||
app.get("/oembed", getOEmbed);
|
||||
|
||||
serve(
|
||||
{
|
||||
...app,
|
||||
|
|
|
|||
25
src/routes/getProfile.tsx
Normal file
25
src/routes/getProfile.tsx
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { Handler } from "hono";
|
||||
import { HTTPException } from "hono/http-exception";
|
||||
import { Profile } from "../components/Profile.tsx";
|
||||
import { fetchProfile } from "../lib/fetchProfile.ts";
|
||||
|
||||
export const getProfile: Handler<
|
||||
HonoEnv,
|
||||
"/profile/:user" | "/https://bsky.app/profile/:user"
|
||||
> = async (c) => {
|
||||
const { user } = c.req.param();
|
||||
const agent = c.get("Agent");
|
||||
const { data, success } = await fetchProfile(agent, { user });
|
||||
if (!success) {
|
||||
throw new HTTPException(500, {
|
||||
message: "Failed to fetch the profile!",
|
||||
});
|
||||
}
|
||||
return c.html(
|
||||
<Profile
|
||||
profile={data}
|
||||
url={c.req.path}
|
||||
appDomain={process.env.FIXBLUESKY_APP_DOMAIN ?? "bsyy.app"}
|
||||
/>
|
||||
);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue