Skip to content

Commit

Permalink
refactor: use useQuery
Browse files Browse the repository at this point in the history
@kasper_573 rewrote the usePronous hoo to use useQuery, thank you! <3
  • Loading branch information
6lr61 committed Sep 13, 2024
1 parent 61e4234 commit 66e3554
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 80 deletions.
27 changes: 27 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"@tanstack/react-query": "^5.56.2",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
Expand Down
36 changes: 23 additions & 13 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,39 @@
import { useContext } from "react";
import { useContext, useMemo } from "react";
import { AuthStateContext } from "./contexts/auth-state/AuthStateContext";
import LoginButton from "./components/LoginButton";
import Chat from "./components/Chat";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

export default function App() {
const authContext = useContext(AuthStateContext);
const queryClient = useMemo(
() =>
new QueryClient({
defaultOptions: { queries: { staleTime: Infinity } },
}),
[]
);

if (!authContext) {
return <p>Missing AuthStateContext provider?</p>;
}

return (
<>
<LoginButton />
{authContext.authState && (
<section>
<p className="bg-pink-50">
Hello: {authContext.authState.user.login}
</p>
<article>
<h2>Chat Messages:</h2>
<Chat />
</article>
</section>
)}
<QueryClientProvider client={queryClient}>
<LoginButton />
{authContext.authState && (
<section>
<p className="bg-pink-50">
Hello: {authContext.authState.user.login}
</p>
<article>
<h2>Chat Messages:</h2>
<Chat />
</article>
</section>
)}
</QueryClientProvider>
</>
);
}
2 changes: 1 addition & 1 deletion src/components/Pronoun.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ export default function Pronoun({
}): ReactElement | undefined {
const pronoun = usePronouns(login);

return <p className="flex-1 font-normal text-sm">{pronoun}</p>;
return <p className="flex-1 font-normal text-sm">{pronoun.data}</p>;
}
84 changes: 18 additions & 66 deletions src/hooks/usePronouns.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from "react";
import { useQuery } from "@tanstack/react-query";

const PRONOUNS_URL = "https://api.pronouns.alejo.io/v1";

Expand All @@ -18,36 +18,27 @@ interface UserEntry {

type PronounResponse = Record<PronounDescription["name"], PronounDescription>;

const cachedPronouns = getPronouns();

async function getPronouns(): Promise<PronounResponse> {
const response = await fetch(`${PRONOUNS_URL}/pronouns`);

if (!response.ok) {
throw new Error(
`getUser: Bad HTTP response: ${response.status.toString()} ${
response.statusText
}`
);
}

return (await response.json()) as PronounResponse;
}

async function getUser(login: string): Promise<UserEntry | null> {
const response = await fetch(`${PRONOUNS_URL}/users/${login}`);

if (response.status === 404) {
try {
const response = await fetch(`${PRONOUNS_URL}/users/${login}`);
return (await response.json()) as UserEntry;
} catch {
return null;
}
}

if (!response.ok) {
throw new Error(
`getUser: Bad HTTP response: ${response.status.toString()} ${
response.statusText
}`
);
}

return (await response.json()) as UserEntry;
async function getUserPronoun(login: string): Promise<string | null> {
const pronouns = await cachedPronouns;
const user = await getUser(login);
const userPronoun = user && pronouns[user.pronoun_id];
return userPronoun ? toString(userPronoun) : null;
}

function toString(description: PronounDescription): string {
Expand All @@ -56,48 +47,9 @@ function toString(description: PronounDescription): string {
: `${description.subject}/${description.object}`;
}

const descriptors = new Map<string, PronounDescription>();
const users = new Map<string, UserEntry | null>();

// FIXME DON'T DO THIS!
(function init() {
if (descriptors.size > 0) {
return;
}

getPronouns()
.then((pronouns) => {
Object.entries(pronouns).forEach(([pronoun, description]) =>
descriptors.set(pronoun, description)
);
})
.catch((error: unknown) => {
console.error("PronounProvider:", error);
});
})();

export function usePronouns(login: string): string | undefined {
const [pronoun, setPronoun] = useState<PronounDescription>();
const user = useMemo(() => users.get(login), [login]);

if (user) {
setPronoun(() => descriptors.get(user.pronoun_id));
}

useEffect(() => {
if (user || user === null) {
return;
}

void getUser(login).then((entry) => {
if (entry === null) {
users.set(login, null);
return;
}

setPronoun(() => descriptors.get(entry.pronoun_id));
});
}, [login, user]);

return pronoun && toString(pronoun);
export function usePronouns(login: string) {
return useQuery({
queryKey: ["userPronoun", login],
queryFn: () => getUserPronoun(login),
});
}

0 comments on commit 66e3554

Please sign in to comment.