@rapidmx/web-client 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -3
- package/apps/shared/components/admin/layout/AdminShell.tsx +3 -2
- package/apps/shared/components/contacts/ContactCard.tsx +38 -12
- package/apps/shared/components/contacts/ContactDetailPane.tsx +25 -5
- package/apps/shared/components/contacts/ContactForm.tsx +36 -5
- package/apps/shared/components/contacts/ContactPhotoField.tsx +86 -0
- package/apps/shared/components/contacts/FavoriteStarButton.tsx +36 -0
- package/apps/shared/components/layout/AppShell.tsx +14 -6
- package/apps/shared/components/mail/ConversationList.tsx +3 -3
- package/apps/shared/components/mail/MessageDetailPane.tsx +18 -18
- package/apps/shared/components/settings/layout/SettingsShell.tsx +3 -3
- package/apps/shared/mail/usePermanentDelete.tsx +14 -7
- package/apps/shared/plugins/pluginIcons.ts +124 -0
- package/apps/shared/plugins/pluginNav.ts +8 -0
- package/apps/shared/plugins/useResolvedRailItems.ts +54 -0
- package/apps/www/contacts/[uid].tsx +1 -0
- package/apps/www/contacts/index.tsx +3 -1
- package/apps/www/index.tsx +43 -35
- package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +1 -1
- package/dist/apps/shared/components/admin/layout/AdminShell.js +3 -2
- package/dist/apps/shared/components/contacts/ContactCard.js +19 -3
- package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +3 -1
- package/dist/apps/shared/components/contacts/ContactDetailPane.js +17 -2
- package/dist/apps/shared/components/contacts/ContactForm.js +20 -2
- package/dist/apps/shared/components/contacts/ContactPhotoField.d.ts +21 -0
- package/dist/apps/shared/components/contacts/ContactPhotoField.js +46 -0
- package/dist/apps/shared/components/contacts/FavoriteStarButton.d.ts +9 -0
- package/dist/apps/shared/components/contacts/FavoriteStarButton.js +12 -0
- package/dist/apps/shared/components/layout/AppShell.d.ts +3 -2
- package/dist/apps/shared/components/layout/AppShell.js +13 -5
- package/dist/apps/shared/components/mail/ConversationList.d.ts +2 -2
- package/dist/apps/shared/components/mail/ConversationList.js +1 -1
- package/dist/apps/shared/components/mail/MessageDetailPane.js +2 -5
- package/dist/apps/shared/components/settings/layout/SettingsShell.js +4 -3
- package/dist/apps/shared/mail/usePermanentDelete.d.ts +2 -0
- package/dist/apps/shared/mail/usePermanentDelete.js +13 -8
- package/dist/apps/shared/plugins/pluginIcons.d.ts +10 -0
- package/dist/apps/shared/plugins/pluginIcons.js +64 -0
- package/dist/apps/shared/plugins/pluginNav.d.ts +8 -0
- package/dist/apps/shared/plugins/useResolvedRailItems.d.ts +12 -0
- package/dist/apps/shared/plugins/useResolvedRailItems.js +47 -0
- package/dist/apps/www/contacts/[uid].js +1 -1
- package/dist/apps/www/contacts/index.js +2 -2
- package/dist/apps/www/index.js +38 -29
- package/dist/lib/components/avatar/ContactAvatar.d.ts +9 -3
- package/dist/lib/components/avatar/ContactAvatar.js +29 -6
- package/dist/lib/components/buttons/CopyIconButton.d.ts +13 -0
- package/dist/lib/components/buttons/CopyIconButton.js +16 -0
- package/dist/lib/contacts/contactsApi.d.ts +12 -0
- package/dist/lib/contacts/contactsApi.js +30 -1
- package/dist/lib/contacts/gravatar.d.ts +12 -0
- package/dist/lib/contacts/gravatar.js +43 -0
- package/lib/components/avatar/ContactAvatar.tsx +43 -7
- package/lib/components/buttons/CopyIconButton.tsx +49 -0
- package/lib/contacts/contactsApi.ts +34 -1
- package/lib/contacts/gravatar.ts +47 -0
- package/package.json +1 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
|
|
6
|
+
/** The `localStorage` key of the privacy preference: `"off"` stops contact avatars from asking Gravatar for a picture. */
|
|
7
|
+
export const GRAVATAR_PREFERENCE_KEY = "rapidmx:gravatar";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Whether avatars may look a person up at Gravatar by the SHA-256 hash of their address (never the address itself). On unless the reader turned
|
|
11
|
+
* it off (`localStorage["rapidmx:gravatar"] = "off"`); a browser without storage keeps the default.
|
|
12
|
+
*/
|
|
13
|
+
export function gravatarEnabled(): boolean {
|
|
14
|
+
try {
|
|
15
|
+
return globalThis.localStorage?.getItem(GRAVATAR_PREFERENCE_KEY) !== "off";
|
|
16
|
+
} catch {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const hashes = new Map<string, Promise<string | undefined>>();
|
|
22
|
+
|
|
23
|
+
/** The lowercase-hex SHA-256 of a trimmed, lowercased `email`, or `undefined` where the browser has no Web Crypto (an insecure page). */
|
|
24
|
+
function hashOf(email: string): Promise<string | undefined> {
|
|
25
|
+
const normalized = email.trim().toLowerCase();
|
|
26
|
+
let hash = hashes.get(normalized);
|
|
27
|
+
if (!hash) {
|
|
28
|
+
hash = (async () => {
|
|
29
|
+
const digest = await globalThis.crypto?.subtle?.digest("SHA-256", new TextEncoder().encode(normalized));
|
|
30
|
+
return digest && Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
31
|
+
})().catch(() => undefined);
|
|
32
|
+
hashes.set(normalized, hash);
|
|
33
|
+
}
|
|
34
|
+
return hash;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The Gravatar picture URL for `email`, `size` pixels square. It answers `404` (`d=404`) for a person with no Gravatar, so an `<img>` fails to load
|
|
39
|
+
* and the caller falls back to initials rather than showing Gravatar's placeholder. `undefined` for an empty address or without Web Crypto.
|
|
40
|
+
*/
|
|
41
|
+
export async function gravatarUrl(email: string, size: number): Promise<string | undefined> {
|
|
42
|
+
if (!email.trim()) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
const hash = await hashOf(email);
|
|
46
|
+
return hash && `https://gravatar.com/avatar/${hash}?s=${Math.max(1, Math.round(size))}&d=404`;
|
|
47
|
+
}
|
package/package.json
CHANGED