fix/companion-consider-all-profile-links (#26158)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { CalComAPIService, UserProfile } from "../services/calcom";
|
||||
import { openInAppBrowser } from "../utils/browser";
|
||||
import { getAvatarUrl } from "../utils/getAvatarUrl";
|
||||
import { CalComLogo } from "./CalComLogo";
|
||||
import { FullScreenModal } from "./FullScreenModal";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
@@ -164,7 +165,7 @@ export function Header() {
|
||||
<ActivityIndicator size="small" color="#666" />
|
||||
) : userProfile?.avatarUrl ? (
|
||||
<Image
|
||||
source={{ uri: userProfile.avatarUrl }}
|
||||
source={{ uri: getAvatarUrl(userProfile.avatarUrl) }}
|
||||
className="h-8 w-8 rounded-full"
|
||||
style={{ width: 32, height: 32, borderRadius: 16 }}
|
||||
/>
|
||||
@@ -203,7 +204,7 @@ export function Header() {
|
||||
<View className="mr-3 h-12 w-12 items-center justify-center rounded-full bg-black">
|
||||
{userProfile?.avatarUrl ? (
|
||||
<Image
|
||||
source={{ uri: userProfile.avatarUrl }}
|
||||
source={{ uri: getAvatarUrl(userProfile.avatarUrl) }}
|
||||
className="h-12 w-12 rounded-full"
|
||||
style={{ width: 48, height: 48, borderRadius: 24 }}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { z } from "zod";
|
||||
|
||||
const CAL_URL = "https://cal.com";
|
||||
const AVATAR_FALLBACK = "/avatar.png";
|
||||
|
||||
/**
|
||||
* Base64 image data URL regex pattern
|
||||
* Matches: data:image/[type];base64,[base64data]
|
||||
*/
|
||||
const BASE64_IMAGE_REGEX =
|
||||
/^data:image\/[^;]+;base64,(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
||||
|
||||
/**
|
||||
* Normalizes avatar URL to a format that can be used by React Native Image component.
|
||||
* Handles three formats:
|
||||
* 1. Absolute HTTPS URLs - returns as-is
|
||||
* 2. Base64 data URLs (data:image/...) - returns as-is
|
||||
* 3. Relative URLs (e.g., /api/avatar/[uuid]) - prefixes with CAL_URL
|
||||
*
|
||||
* @param avatarUrl - The avatar URL from the API (can be absolute URL, base64, or relative path)
|
||||
* @returns A normalized URL that can be used by React Native Image component, or fallback URL
|
||||
*
|
||||
* @example
|
||||
* getAvatarUrl("https://example.com/avatar.jpg") // "https://example.com/avatar.jpg"
|
||||
* getAvatarUrl("data:image/png;base64,iVBORw0KG...") // "data:image/png;base64,iVBORw0KG..."
|
||||
* getAvatarUrl("/api/avatar/123") // "https://cal.com/api/avatar/123"
|
||||
* getAvatarUrl(undefined) // "https://cal.com/avatar.png"
|
||||
*/
|
||||
export const getAvatarUrl = (avatarUrl: string | null | undefined): string => {
|
||||
if (!avatarUrl) {
|
||||
return CAL_URL + AVATAR_FALLBACK;
|
||||
}
|
||||
|
||||
// Check if it's a base64 data URL
|
||||
if (BASE64_IMAGE_REGEX.test(avatarUrl)) {
|
||||
return avatarUrl;
|
||||
}
|
||||
|
||||
// Check if it's already an absolute URL (HTTPS or HTTP)
|
||||
const isAbsoluteUrl = z.string().url().safeParse(avatarUrl).success;
|
||||
if (isAbsoluteUrl) {
|
||||
return avatarUrl;
|
||||
}
|
||||
|
||||
// Treat as relative URL and prefix with CAL_URL
|
||||
// Ensure the relative URL starts with /
|
||||
const relativePath = avatarUrl.startsWith("/") ? avatarUrl : `/${avatarUrl}`;
|
||||
return CAL_URL + relativePath;
|
||||
};
|
||||
@@ -39,6 +39,9 @@ export { slugify } from "./slugify";
|
||||
// App icon utilities
|
||||
export { getAppIconUrl } from "./getAppIconUrl";
|
||||
|
||||
// Avatar utilities
|
||||
export { getAvatarUrl } from "./getAvatarUrl";
|
||||
|
||||
// Default location utilities
|
||||
export {
|
||||
defaultLocations,
|
||||
|
||||
Reference in New Issue
Block a user