From 7470d389a7ebbf5a6cf194e8183db3c14dc1f02e Mon Sep 17 00:00:00 2001
From: Matthieu Jacq <67386567+matthieujacq@users.noreply.github.com>
Date: Wed, 27 Sep 2023 14:41:08 +0200
Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=91=A4=20Implement=20gravatar=20(?=
=?UTF-8?q?#1268)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* ✨ Implement gravatar
* ♻️ refact gravatar url generation with a custom hook
* review: do not add a default value to the email if undefined
---
.../ChatsListItem/components/UserButton.tsx | 13 ++++++--
.../ChatsListItem/hooks/useGravatar.ts | 30 +++++++++++++++++++
frontend/next.config.js | 6 +++-
3 files changed, 46 insertions(+), 3 deletions(-)
create mode 100644 frontend/app/chat/components/ChatsList/components/ChatsListItem/hooks/useGravatar.ts
diff --git a/frontend/app/chat/components/ChatsList/components/ChatsListItem/components/UserButton.tsx b/frontend/app/chat/components/ChatsList/components/ChatsListItem/components/UserButton.tsx
index 2128e8158ed8..f8c9ff243580 100644
--- a/frontend/app/chat/components/ChatsList/components/ChatsListItem/components/UserButton.tsx
+++ b/frontend/app/chat/components/ChatsList/components/ChatsListItem/components/UserButton.tsx
@@ -1,16 +1,25 @@
+import Image from "next/image";
import Link from "next/link";
-import { MdPerson } from "react-icons/md";
import { useSupabase } from "@/lib/context/SupabaseProvider";
+import { useGravatar } from "../hooks/useGravatar";
import { sidebarLinkStyle } from "../styles/SidebarLinkStyle";
export const UserButton = (): JSX.Element => {
const { session } = useSupabase();
+ const { gravatarUrl } = useGravatar();
return (
-
+
+
+
{session?.user.email ?? ""}
diff --git a/frontend/app/chat/components/ChatsList/components/ChatsListItem/hooks/useGravatar.ts b/frontend/app/chat/components/ChatsList/components/ChatsListItem/hooks/useGravatar.ts
new file mode 100644
index 000000000000..ded77c203efb
--- /dev/null
+++ b/frontend/app/chat/components/ChatsList/components/ChatsListItem/hooks/useGravatar.ts
@@ -0,0 +1,30 @@
+import { createHash } from "crypto";
+import { useEffect, useState } from "react";
+
+import { useSupabase } from "@/lib/context/SupabaseProvider";
+
+// Gravatar images may be requested just like a normal image, using an IMG tag. To get an image specific to a user, you must first calculate their email hash.
+// The most basic image request URL looks like this:
+// https://www.gravatar.com/avatar/HASH
+
+const computeGravatarUrl = (email?: string) => {
+ const hash = createHash("md5")
+ .update(typeof email === "string" ? email.trim().toLowerCase() : "")
+ .digest("hex");
+
+ return `https://www.gravatar.com/avatar/${hash}?d=mp`;
+};
+
+export const useGravatar = (): { gravatarUrl: string } => {
+ const { session } = useSupabase();
+ const [gravatarUrl, setGravatarUrl] = useState(computeGravatarUrl());
+
+ const email = session?.user.email;
+
+ useEffect(() => {
+ const computedUrl = computeGravatarUrl(email);
+ setGravatarUrl(computedUrl);
+ }, [email]);
+
+ return { gravatarUrl };
+};
diff --git a/frontend/next.config.js b/frontend/next.config.js
index 5c5440d4c3fd..fc3f56345703 100644
--- a/frontend/next.config.js
+++ b/frontend/next.config.js
@@ -1,6 +1,10 @@
const nextConfig = {
images: {
- domains: ["www.quivr.app", "quivr-cms.s3.eu-west-3.amazonaws.com"]
+ domains: [
+ "www.quivr.app",
+ "quivr-cms.s3.eu-west-3.amazonaws.com",
+ "www.gravatar.com",
+ ],
},
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
async headers() {