import Constants from "expo-constants"; /** * Turns whatever sits in `drivers.profile_image_url` into something an * `` can load. * * That column holds one of two things. A driver who took their photo in the * app stores an opaque name ("a1b2….jpg") that only means anything to * /(api)/driver/photo; an owner who filled the field in from the admin * dashboard stores a full external URL. Both have to render, so the shape of * the value decides how it is read — which also means older profiles carrying * a real URL keep working untouched. */ const ABSOLUTE = /^(https?:|data:|file:|blob:)/i; /** * The origin an should fetch from. * * `fetchAPI` gets away with relative paths because expo-router resolves them, * and in development it resolves them against the Metro dev server rather than * the configured origin. An URL has to be absolute, so it has to make * the same choice by hand — otherwise every API call goes to the laptop while * every avatar goes to production (or, worse, to the placeholder origin in * .env, and silently renders nothing). */ const apiOrigin = (): string => { if (__DEV__) { const hostUri = Constants.expoConfig?.hostUri; if (hostUri) return `http://${hostUri}`; } return (process.env.EXPO_PUBLIC_SERVER_URL ?? "").replace(/\/+$/, ""); }; export const driverPhotoUri = (value?: string | null): string | undefined => { if (!value) return undefined; if (ABSOLUTE.test(value)) return value; const origin = apiOrigin(); if (!origin) return undefined; // The literal "(api)" is part of the path — this app's routes are addressed // that way throughout, not as an expo-router group that gets stripped. return `${origin}/(api)/driver/photo?name=${encodeURIComponent(value)}`; };