committed by
GitHub
parent
a07025422e
commit
6b9696e715
@@ -12,6 +12,14 @@ const config = {
|
||||
esmExternals: "loose",
|
||||
serverComponentsExternalPackages: ["bullmq"],
|
||||
},
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "www.gravatar.com",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
@@ -1,15 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Table,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableHead,
|
||||
TableBody,
|
||||
TableCell,
|
||||
} from "@unsend/ui/src/table";
|
||||
import { api } from "~/trpc/react";
|
||||
import { useUrlState } from "~/hooks/useUrlState";
|
||||
import { Button } from "@unsend/ui/src/button";
|
||||
import {
|
||||
Select,
|
||||
@@ -18,7 +8,19 @@ import {
|
||||
SelectTrigger,
|
||||
} from "@unsend/ui/src/select";
|
||||
import Spinner from "@unsend/ui/src/spinner";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@unsend/ui/src/table";
|
||||
import { formatDistanceToNow } from "date-fns";
|
||||
import Image from "next/image";
|
||||
import { useUrlState } from "~/hooks/useUrlState";
|
||||
import { api } from "~/trpc/react";
|
||||
import { getGravatarUrl } from "~/utils/gravatar-utils";
|
||||
import DeleteContact from "./delete-contact";
|
||||
import EditContact from "./edit-contact";
|
||||
|
||||
@@ -89,7 +91,21 @@ export default function ContactList({
|
||||
) : contactsQuery.data?.contacts.length ? (
|
||||
contactsQuery.data?.contacts.map((contact) => (
|
||||
<TableRow key={contact.id} className="">
|
||||
<TableCell className="font-medium">{contact.email}</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
<div className="flex items-center gap-2">
|
||||
<Image
|
||||
src={getGravatarUrl(contact.email, {
|
||||
size: 35,
|
||||
defaultImage: "identicon",
|
||||
})}
|
||||
alt={contact.email + "'s gravatar"}
|
||||
width={35}
|
||||
height={35}
|
||||
className="rounded-full"
|
||||
/>
|
||||
{contact.email}
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div
|
||||
className={`text-center w-[130px] rounded capitalize py-1 text-xs ${
|
||||
|
62
apps/web/src/utils/gravatar-utils.ts
Normal file
62
apps/web/src/utils/gravatar-utils.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import crypto from "crypto";
|
||||
|
||||
/**
|
||||
* Possible Gravatar rating values: 'g' (general), 'pg' (parental guidance),
|
||||
* 'r' (restricted), or 'x' (explicit).
|
||||
*/
|
||||
export type GravatarRating = "g" | "pg" | "r" | "x";
|
||||
|
||||
/**
|
||||
* Common default image options in Gravatar.
|
||||
* Can also be a URL (string) for a custom default image.
|
||||
*/
|
||||
export type GravatarDefaultImage =
|
||||
| "404"
|
||||
| "mp"
|
||||
| "identicon"
|
||||
| "monsterid"
|
||||
| "wavatar"
|
||||
| "retro"
|
||||
| "robohash"
|
||||
| "blank";
|
||||
|
||||
export interface GravatarOptions {
|
||||
size?: number; // specify the size (in pixels)
|
||||
defaultImage?: GravatarDefaultImage; // default image
|
||||
rating?: GravatarRating; // image rating
|
||||
}
|
||||
|
||||
export function getGravatarUrl(
|
||||
email: string,
|
||||
options: GravatarOptions = {
|
||||
size: 80,
|
||||
defaultImage: "identicon",
|
||||
rating: "g",
|
||||
},
|
||||
) {
|
||||
const trimmedEmail = email.trim().toLowerCase();
|
||||
const hash = crypto.createHash("sha256").update(trimmedEmail).digest("hex");
|
||||
|
||||
// Base Gravatar URL
|
||||
const baseUrl = "https://www.gravatar.com/avatar/";
|
||||
|
||||
// Use URLSearchParams to build query string
|
||||
const queryParams = new URLSearchParams();
|
||||
|
||||
if (options.size) {
|
||||
queryParams.set("s", options.size.toString());
|
||||
}
|
||||
if (options.defaultImage) {
|
||||
queryParams.set("d", options.defaultImage);
|
||||
}
|
||||
if (options.rating) {
|
||||
queryParams.set("r", options.rating);
|
||||
}
|
||||
|
||||
const queryString = queryParams.toString();
|
||||
const finalUrl = queryString
|
||||
? `${baseUrl}${hash}?${queryString}`
|
||||
: `${baseUrl}${hash}`;
|
||||
|
||||
return finalUrl;
|
||||
}
|
Reference in New Issue
Block a user