From 0a37393244947c51348acbc8ffe6e0d1ce8e85b4 Mon Sep 17 00:00:00 2001 From: Dennis Falling Date: Tue, 7 Jul 2026 22:19:55 +0200 Subject: [PATCH] Fix Wikimedia photos still not loading on Android MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Image.android.js only forwards the `headers` prop to the native view when `source` resolves to an array — for a plain `{uri, headers}` object it drops them silently, so the User-Agent fix from #38 never actually reached the network request. Return a single-element array instead so Android's Image pipeline picks up the header. Co-Authored-By: Claude Sonnet 5 --- __tests__/photoImageSource.test.ts | 20 ++++++++++++++++++++ src/photos/photoImageSource.ts | 10 ++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 __tests__/photoImageSource.test.ts diff --git a/__tests__/photoImageSource.test.ts b/__tests__/photoImageSource.test.ts new file mode 100644 index 0000000..3349cac --- /dev/null +++ b/__tests__/photoImageSource.test.ts @@ -0,0 +1,20 @@ +/** + * @format + */ + +import {photoImageSource} from '../src/photos/photoImageSource'; + +// Must stay an array: Image.android.js only forwards `headers` to the +// native view when `source` resolves to an array, so a plain +// `{uri, headers}` object silently drops the header on Android. +test('returns a single-element array so Android forwards the headers', () => { + const source = photoImageSource('https://example.com/photo.jpg'); + expect(Array.isArray(source)).toBe(true); + expect(source).toHaveLength(1); +}); + +test('attaches a descriptive User-Agent header to the uri', () => { + const [source] = photoImageSource('https://example.com/photo.jpg'); + expect(source.uri).toBe('https://example.com/photo.jpg'); + expect(source.headers?.['User-Agent']).toMatch(/^Culpeos\//); +}); diff --git a/src/photos/photoImageSource.ts b/src/photos/photoImageSource.ts index de6b381..5d2c595 100644 --- a/src/photos/photoImageSource.ts +++ b/src/photos/photoImageSource.ts @@ -9,6 +9,12 @@ import type {ImageURISource} from 'react-native'; const USER_AGENT = 'Culpeos/0.0.1 (https://culpeos.com)'; // Builds an Image `source` for a photo URL with a User-Agent header attached. -export function photoImageSource(uri: string): ImageURISource { - return {uri, headers: {'User-Agent': USER_AGENT}}; +// +// Must be a single-element array, not a plain `{uri, headers}` object: on +// Android, `Image`'s native-props translation (Libraries/Image/Image.android.js) +// only forwards `headers` to the native view when `source` resolves to an +// array — for a single object it drops them silently, so the request never +// carries the header and the fix above has no effect. +export function photoImageSource(uri: string): ImageURISource[] { + return [{uri, headers: {'User-Agent': USER_AGENT}}]; }