mattermost-mobile/scripts/android-16kb-pagesize/9325-full.diff
Nick Misasi 46d46790b5
Fix Android image loads by attaching auth headers (#9554)
* Fix images not loading on android"

* Update app/components/expo_image/index.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update snapshots and remove accept

* Fix 16KB page size patch failing due to stale diff context (#9555)

The expo_image/index.tsx hunks in 9325-full.diff were generated before
the NetworkManager/header-handling code was added to ExpoImage. The stale
context lines caused patch's fuzzy matching to apply ExpoImage hunks to
ExpoImageBackground instead, then ExpoImageBackground hunks failed
because those sections were already modified.

Regenerated the expo_image diff hunks to match the current file state
with proper context lines for both ExpoImage (with header handling) and
ExpoImageBackground components.

https://claude.ai/code/session_01SGXWQzxrcPpWsq2YrjoUwd

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Your Name <larkox@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-26 21:36:03 -05:00

398 lines
20 KiB
Diff

diff --git a/android/buildscript-gradle.lockfile b/android/buildscript-gradle.lockfile
index dfde0b3d60..3a4a440688 100644
--- a/android/buildscript-gradle.lockfile
+++ b/android/buildscript-gradle.lockfile
@@ -130,6 +130,7 @@ org.jetbrains.kotlin:kotlin-gradle-plugins-bom:2.0.21=classpath
org.jetbrains.kotlin:kotlin-klib-commonizer-api:2.0.21=classpath
org.jetbrains.kotlin:kotlin-native-utils:2.0.21=classpath
org.jetbrains.kotlin:kotlin-reflect:1.9.20=classpath
+org.jetbrains.kotlin:kotlin-stdlib-common:2.0.21=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.20=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.20=classpath
org.jetbrains.kotlin:kotlin-stdlib:2.0.21=classpath
@@ -137,6 +138,11 @@ org.jetbrains.kotlin:kotlin-tooling-core:2.0.21=classpath
org.jetbrains.kotlin:kotlin-util-io:2.0.21=classpath
org.jetbrains.kotlin:kotlin-util-klib:2.0.21=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=classpath
+org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.3=classpath
+org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.6.3=classpath
+org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.3=classpath
+org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.6.3=classpath
+org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3=classpath
org.jetbrains:annotations:23.0.0=classpath
org.jvnet.staxex:stax-ex:1.8.1=classpath
org.ow2.asm:asm-analysis:9.6=classpath
diff --git a/app.json b/app.json
index 08eb45fcd9..914911c17a 100644
--- a/app.json
+++ b/app.json
@@ -1,4 +1,7 @@
{
"name": "Mattermost",
- "displayName": "Mattermost"
+ "displayName": "Mattermost",
+ "plugins": [
+ "expo-web-browser"
+ ]
}
diff --git a/app/components/expo_image/index.tsx b/app/components/expo_image/index.tsx
index b2723fb..1ed5e15 100644
--- a/app/components/expo_image/index.tsx
+++ b/app/components/expo_image/index.tsx
@@ -9,6 +9,8 @@ import {useServerUrl} from '@context/server';
import NetworkManager from '@managers/network_manager';
import {urlSafeBase64Encode} from '@utils/security';
+import type {SharedRefType} from 'expo';
+
type ExpoImagePropsWithId = ImageProps & {id: string};
type ExpoImagePropsMemoryOnly = ImageProps & {cachePolicy: 'memory'; id?: string};
type ExpoImageProps = ExpoImagePropsWithId | ExpoImagePropsMemoryOnly;
@@ -54,8 +56,8 @@ const ExpoImage = forwardRef<Image, ExpoImageProps>(({id, ...props}, ref) => {
* for filesystem path compatibility (avoiding special characters in directory names).
*/
const cachePath = useMemo(() => urlSafeBase64Encode(serverUrl), [serverUrl]);
- const source: ImageSource = useMemo(() => {
- if (typeof props.source === 'number') {
+ const source: ImageSource | string | number | ImageSource[] | string[] | SharedRefType<'image'> | null | undefined = useMemo(() => {
+ if (typeof props.source === 'number' || typeof props.source === 'string' || Array.isArray(props.source) || !props.source) {
return props.source;
}
@@ -63,7 +65,7 @@ const ExpoImage = forwardRef<Image, ExpoImageProps>(({id, ...props}, ref) => {
delete sourceHeaders?.Accept;
// Only add cacheKey and cachePath if id is provided (i.e., not memory-only caching)
- if (id) {
+ if (id && typeof props.source === 'object' && 'uri' in props.source) {
return {
...props.source,
headers: sourceHeaders,
@@ -79,8 +81,8 @@ const ExpoImage = forwardRef<Image, ExpoImageProps>(({id, ...props}, ref) => {
}, [id, props.source, cachePath, requestHeaders, serverUrl]);
// Process placeholder to add cachePath and cacheKey if it has a uri
- const placeholder: ImageSource | undefined = useMemo(() => {
- if (!props.placeholder || typeof props.placeholder === 'number' || typeof props.placeholder === 'string') {
+ const placeholder: ImageSource | string | number | ImageSource[] | string[] | SharedRefType<'image'> | null | undefined = useMemo(() => {
+ if (!props.placeholder || typeof props.placeholder === 'number' || typeof props.placeholder === 'string' || Array.isArray(props.placeholder)) {
return props.placeholder;
}
@@ -88,7 +90,7 @@ const ExpoImage = forwardRef<Image, ExpoImageProps>(({id, ...props}, ref) => {
delete placeholderHeaders?.Accept;
// If placeholder has a uri and id is provided, add cachePath and cacheKey
- if (props.placeholder.uri && id) {
+ if (typeof props.placeholder === 'object' && 'uri' in props.placeholder && props.placeholder.uri && id) {
return {
...props.placeholder,
headers: placeholderHeaders,
@@ -117,13 +119,13 @@ ExpoImage.displayName = 'ExpoImage';
const ExpoImageBackground = ({id, ...props}: ExpoImageBackgroundProps) => {
const serverUrl = useServerUrl();
const cachePath = useMemo(() => urlSafeBase64Encode(serverUrl), [serverUrl]);
- const source: ImageSource = useMemo(() => {
- if (typeof props.source === 'number') {
+ const source: ImageSource | string | number | ImageSource[] | string[] | SharedRefType<'image'> | null | undefined = useMemo(() => {
+ if (typeof props.source === 'number' || typeof props.source === 'string' || Array.isArray(props.source) || !props.source) {
return props.source;
}
// Only add cacheKey and cachePath if id is provided (i.e., not memory-only caching)
- if (id) {
+ if (id && typeof props.source === 'object' && 'uri' in props.source) {
return {
...props.source,
cacheKey: id,
@@ -135,13 +137,13 @@ const ExpoImageBackground = ({id, ...props}: ExpoImageBackgroundProps) => {
}, [id, props.source, cachePath]);
// Process placeholder to add cachePath and cacheKey if it has a uri
- const placeholder: ImageSource | undefined = useMemo(() => {
- if (!props.placeholder || typeof props.placeholder === 'number' || typeof props.placeholder === 'string') {
+ const placeholder: ImageSource | string | number | ImageSource[] | string[] | SharedRefType<'image'> | null | undefined = useMemo(() => {
+ if (!props.placeholder || typeof props.placeholder === 'number' || typeof props.placeholder === 'string' || Array.isArray(props.placeholder)) {
return props.placeholder;
}
// If placeholder has a uri and id is provided, add cachePath and cacheKey
- if (props.placeholder.uri && id) {
+ if (typeof props.placeholder === 'object' && 'uri' in props.placeholder && props.placeholder.uri && id) {
return {
...props.placeholder,
cacheKey: `${id}-thumb`,
diff --git a/package.json b/package.json
index 80a6ffba49..47bb39cdcb 100644
--- a/package.json
+++ b/package.json
@@ -53,15 +53,17 @@
"deep-equal": "2.2.3",
"deepmerge": "4.3.1",
"emoji-regex": "10.4.0",
- "expo": "52.0.47",
+ "expo": "53.0.24",
"expo-application": "6.0.2",
+ "expo-constants": "17.1.7",
"expo-crypto": "14.0.2",
"expo-device": "7.0.3",
- "expo-image": "2.0.7",
- "expo-linear-gradient": "14.0.2",
+ "expo-file-system": "18.1.11",
+ "expo-image": "2.4.1",
+ "expo-linear-gradient": "14.1.5",
"expo-store-review": "8.0.1",
"expo-video-thumbnails": "9.0.3",
- "expo-web-browser": "14.0.2",
+ "expo-web-browser": "~14.2.0",
"fflate": "0.8.2",
"fuse.js": "7.1.0",
"html-entities": "2.6.0",
diff --git a/patches/expo-file-system+18.0.12.patch b/patches/expo-file-system+18.1.11.patch
similarity index 100%
rename from patches/expo-file-system+18.0.12.patch
rename to patches/expo-file-system+18.1.11.patch
diff --git a/patches/expo-image+2.0.7.patch b/patches/expo-image+2.4.1.patch
similarity index 92%
rename from patches/expo-image+2.0.7.patch
rename to patches/expo-image+2.4.1.patch
index 69520d0097..bece1d88a3 100644
--- a/patches/expo-image+2.0.7.patch
+++ b/patches/expo-image+2.4.1.patch
@@ -1,16 +1,3 @@
-diff --git a/node_modules/expo-image/android/build.gradle b/node_modules/expo-image/android/build.gradle
-index 11492a2..b6bb941 100644
---- a/node_modules/expo-image/android/build.gradle
-+++ b/node_modules/expo-image/android/build.gradle
-@@ -44,7 +44,7 @@ dependencies {
- kapt "com.github.bumptech.glide:compiler:${GLIDE_VERSION}"
- api 'com.caverock:androidsvg-aar:1.4'
-
-- implementation "com.github.penfeizhou.android.animation:glide-plugin:3.0.2"
-+ implementation("com.github.penfeizhou.android.animation:glide-plugin:3.0.3")
- implementation "com.github.bumptech.glide:avif-integration:${GLIDE_VERSION}"
-
- api 'com.github.bumptech.glide:okhttp3-integration:4.11.0'
diff --git a/node_modules/expo-image/android/src/main/java/expo/modules/image/ExpoImageAppGlideModule.kt b/node_modules/expo-image/android/src/main/java/expo/modules/image/ExpoImageAppGlideModule.kt
index 5735515..dbbb924 100644
--- a/node_modules/expo-image/android/src/main/java/expo/modules/image/ExpoImageAppGlideModule.kt
@@ -36,7 +23,7 @@ index 5735515..dbbb924 100644
}
}
diff --git a/node_modules/expo-image/android/src/main/java/expo/modules/image/ExpoImageModule.kt b/node_modules/expo-image/android/src/main/java/expo/modules/image/ExpoImageModule.kt
-index 73641a0..186fe54 100644
+index 0170d9b..169425c 100644
--- a/node_modules/expo-image/android/src/main/java/expo/modules/image/ExpoImageModule.kt
+++ b/node_modules/expo-image/android/src/main/java/expo/modules/image/ExpoImageModule.kt
@@ -148,13 +148,17 @@ class ExpoImageModule : Module() {
@@ -299,10 +286,10 @@ index 72ad8fa..60ceaac 100644
private fun getCustomHeaders(): Headers {
diff --git a/node_modules/expo-image/build/Image.d.ts b/node_modules/expo-image/build/Image.d.ts
-index 44ea175..14b20d9 100644
+index 765a3db..6982c6d 100644
--- a/node_modules/expo-image/build/Image.d.ts
+++ b/node_modules/expo-image/build/Image.d.ts
-@@ -33,6 +33,16 @@ export declare class Image extends React.PureComponent<ImageProps> {
+@@ -35,6 +35,16 @@ export declare class Image extends React.PureComponent<ImageProps> {
* finished prefetching.
*/
static prefetch(urls: string | string[], options?: ImagePrefetchOptions): Promise<boolean>;
@@ -319,7 +306,7 @@ index 44ea175..14b20d9 100644
/**
* Asynchronously clears all images stored in memory.
* @platform android
-@@ -46,11 +56,13 @@ export declare class Image extends React.PureComponent<ImageProps> {
+@@ -48,11 +58,13 @@ export declare class Image extends React.PureComponent<ImageProps> {
* Asynchronously clears all images from the disk cache.
* @platform android
* @platform ios
@@ -335,10 +322,10 @@ index 44ea175..14b20d9 100644
* Asynchronously checks if an image exists in the disk cache and resolves to
* the path of the cached image if it does.
diff --git a/node_modules/expo-image/build/Image.types.d.ts b/node_modules/expo-image/build/Image.types.d.ts
-index 493fd68..1f71756 100644
+index f690040..af43e4a 100644
--- a/node_modules/expo-image/build/Image.types.d.ts
+++ b/node_modules/expo-image/build/Image.types.d.ts
-@@ -46,6 +46,14 @@ export type ImageSource = {
+@@ -45,6 +45,14 @@ export type ImageSource = {
* If not provided, the `uri` is used also as the cache key.
*/
cacheKey?: string;
@@ -354,15 +341,16 @@ index 493fd68..1f71756 100644
* The max width of the viewport for which this source should be selected.
* Has no effect if `source` prop is not an array or has only 1 element.
diff --git a/node_modules/expo-image/ios/ExpoImage.podspec b/node_modules/expo-image/ios/ExpoImage.podspec
-index 21bef71..d662d23 100644
+index 40e2b49..695f137 100644
--- a/node_modules/expo-image/ios/ExpoImage.podspec
+++ b/node_modules/expo-image/ios/ExpoImage.podspec
-@@ -20,9 +20,7 @@ Pod::Spec.new do |s|
+@@ -20,10 +20,8 @@ Pod::Spec.new do |s|
s.dependency 'ExpoModulesCore'
- s.dependency 'SDWebImage', '~> 5.19.1'
+ s.dependency 'SDWebImage', '~> 5.21.0'
- s.dependency 'SDWebImageAVIFCoder', '~> 0.11.0'
s.dependency 'SDWebImageSVGCoder', '~> 1.7.0'
+ s.dependency 'SDWebImageWebPCoder', '~> 0.14.6'
- s.dependency 'libavif/libdav1d'
# Swift/Objective-C compatibility
@@ -384,7 +372,7 @@ index a0dacf9..36a2908 100644
if let maxSize {
context[.imageThumbnailPixelSize] = maxSize
diff --git a/node_modules/expo-image/ios/ImageModule.swift b/node_modules/expo-image/ios/ImageModule.swift
-index 4bab386..4d9ca4f 100644
+index 1451696..3985a30 100644
--- a/node_modules/expo-image/ios/ImageModule.swift
+++ b/node_modules/expo-image/ios/ImageModule.swift
@@ -2,7 +2,6 @@
@@ -395,7 +383,7 @@ index 4bab386..4d9ca4f 100644
import SDWebImageSVGCoder
public final class ImageModule: Module {
-@@ -150,6 +149,36 @@ public final class ImageModule: Module {
+@@ -170,6 +169,36 @@ public final class ImageModule: Module {
}
}
@@ -432,7 +420,7 @@ index 4bab386..4d9ca4f 100644
AsyncFunction("generateBlurhashAsync") { (url: URL, numberOfComponents: CGSize, promise: Promise) in
let downloader = SDWebImageDownloader()
let parsedNumberOfComponents = (Int(numberOfComponents.width), Int(numberOfComponents.height))
-@@ -170,9 +199,22 @@ public final class ImageModule: Module {
+@@ -190,9 +219,22 @@ public final class ImageModule: Module {
return true
}
@@ -458,10 +446,10 @@ index 4bab386..4d9ca4f 100644
}
}
-@@ -211,7 +253,6 @@ public final class ImageModule: Module {
+@@ -230,7 +272,6 @@ public final class ImageModule: Module {
+
static func registerCoders() {
- // By default Animated WebP is not supported
- SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared)
+ SDImageCodersManager.shared.addCoder(WebPCoder.shared)
- SDImageCodersManager.shared.addCoder(SDImageAVIFCoder.shared)
SDImageCodersManager.shared.addCoder(SDImageSVGCoder.shared)
SDImageCodersManager.shared.addCoder(SDImageHEICCoder.shared)
@@ -481,19 +469,19 @@ index 88082fd..5025f0e 100644
return width * height * scale * scale
}
diff --git a/node_modules/expo-image/ios/ImageUtils.swift b/node_modules/expo-image/ios/ImageUtils.swift
-index 34f2231..a58943e 100644
+index e24e776..fc32c79 100644
--- a/node_modules/expo-image/ios/ImageUtils.swift
+++ b/node_modules/expo-image/ios/ImageUtils.swift
-@@ -172,7 +172,7 @@ func createCacheKeyFilter(_ cacheKey: String?) -> SDWebImageCacheKeyFilter? {
+@@ -158,7 +158,7 @@ func createCacheKeyFilter(_ cacheKey: String?) -> SDWebImageCacheKeyFilter? {
/**
Creates a default image context based on the source and the cache policy.
*/
--func createSDWebImageContext(forSource source: ImageSource, cachePolicy: ImageCachePolicy = .disk) -> SDWebImageContext {
-+func createSDWebImageContext(forSource source: ImageSource, cachePolicy: ImageCachePolicy = .disk, customCache: SDImageCache? = nil) -> SDWebImageContext {
+-func createSDWebImageContext(forSource source: ImageSource, cachePolicy: ImageCachePolicy = .disk, useAppleWebpCodec: Bool = true) -> SDWebImageContext {
++func createSDWebImageContext(forSource source: ImageSource, cachePolicy: ImageCachePolicy = .disk, customCache: SDImageCache? = nil, useAppleWebpCodec: Bool = true) -> SDWebImageContext {
var context = SDWebImageContext()
// Modify URL request to add headers.
-@@ -209,6 +209,12 @@ func createSDWebImageContext(forSource source: ImageSource, cachePolicy: ImageCa
+@@ -202,6 +202,12 @@ func createSDWebImageContext(forSource source: ImageSource, cachePolicy: ImageCa
// Some loaders (e.g. blurhash) may need access to the source.
context[ImageView.contextSourceKey] = source
@@ -507,7 +495,7 @@ index 34f2231..a58943e 100644
}
diff --git a/node_modules/expo-image/ios/ImageView.swift b/node_modules/expo-image/ios/ImageView.swift
-index 2ab4cba..0d423ea 100644
+index bb6f6a5..de3468b 100644
--- a/node_modules/expo-image/ios/ImageView.swift
+++ b/node_modules/expo-image/ios/ImageView.swift
@@ -8,6 +8,79 @@ import VisionKit
@@ -590,33 +578,33 @@ index 2ab4cba..0d423ea 100644
// swiftlint:disable:next type_body_length
public final class ImageView: ExpoView {
static let contextSourceKey = SDWebImageContextOption(rawValue: "source")
-@@ -129,7 +202,10 @@ public final class ImageView: ExpoView {
+@@ -152,7 +225,10 @@ public final class ImageView: ExpoView {
if sdImageView.image == nil {
sdImageView.contentMode = contentFit.toContentMode()
}
-- var context = createSDWebImageContext(forSource: source, cachePolicy: cachePolicy)
+- var context = createSDWebImageContext(forSource: source, cachePolicy: cachePolicy, useAppleWebpCodec: useAppleWebpCodec)
+
+ // Get custom cache if cachePath is specified
+ let customCache = CachePathManager.shared.getCacheForPath(source.cachePath)
-+ var context = createSDWebImageContext(forSource: source, cachePolicy: cachePolicy, customCache: customCache)
++ var context = createSDWebImageContext(forSource: source, cachePolicy: cachePolicy, customCache: customCache, useAppleWebpCodec: useAppleWebpCodec)
// Cancel currently running load requests.
cancelPendingOperation()
-@@ -311,7 +387,8 @@ public final class ImageView: ExpoView {
+@@ -337,7 +413,8 @@ public final class ImageView: ExpoView {
// to cache them or apply the same policy as with the proper image?
// Basically they are also cached in memory as the `placeholderImage` property,
// so just `disk` policy sounds like a good idea.
-- var context = createSDWebImageContext(forSource: placeholder, cachePolicy: .disk)
+- var context = createSDWebImageContext(forSource: placeholder, cachePolicy: .disk, useAppleWebpCodec: useAppleWebpCodec)
+ let customCache = CachePathManager.shared.getCacheForPath(placeholder.cachePath)
-+ var context = createSDWebImageContext(forSource: placeholder, cachePolicy: .disk, customCache: customCache)
++ var context = createSDWebImageContext(forSource: placeholder, cachePolicy: .disk, customCache: customCache, useAppleWebpCodec: useAppleWebpCodec)
let isPlaceholderHash = placeholder.isBlurhash || placeholder.isThumbhash
diff --git a/node_modules/expo-image/src/Image.tsx b/node_modules/expo-image/src/Image.tsx
-index 7721bd9..584cb02 100644
+index c52e711..c392133 100644
--- a/node_modules/expo-image/src/Image.tsx
+++ b/node_modules/expo-image/src/Image.tsx
-@@ -69,8 +69,18 @@ export class Image extends React.PureComponent<ImageProps> {
+@@ -70,8 +70,18 @@ export class Image extends React.PureComponent<ImageProps> {
* finished prefetching.
*/
static async prefetch(urls: string | string[], options?: ImagePrefetchOptions): Promise<boolean>;
@@ -636,7 +624,7 @@ index 7721bd9..584cb02 100644
options?: ImagePrefetchOptions['cachePolicy'] | ImagePrefetchOptions
): Promise<boolean> {
let cachePolicy: ImagePrefetchOptions['cachePolicy'] = 'memory-disk';
-@@ -85,7 +95,18 @@ export class Image extends React.PureComponent<ImageProps> {
+@@ -86,7 +96,18 @@ export class Image extends React.PureComponent<ImageProps> {
break;
}
@@ -655,12 +643,23 @@ index 7721bd9..584cb02 100644
+ }
}
+ /**
+@@ -109,8 +130,8 @@ export class Image extends React.PureComponent<ImageProps> {
+ * It may resolve to `false` on Android when the activity is no longer available.
+ * Resolves to `false` on Web.
+ */
+- static async clearDiskCache(): Promise<boolean> {
+- return await ImageModule.clearDiskCache();
++ static async clearDiskCache(path?: string): Promise<boolean> {
++ return await ImageModule.clearDiskCache(path);
+ }
+
/**
diff --git a/node_modules/expo-image/src/Image.types.ts b/node_modules/expo-image/src/Image.types.ts
-index 63445be..c67ad0c 100644
+index 0b4e7a5..efbe5ee 100644
--- a/node_modules/expo-image/src/Image.types.ts
+++ b/node_modules/expo-image/src/Image.types.ts
-@@ -51,6 +51,16 @@ export type ImageSource = {
+@@ -50,6 +50,16 @@ export type ImageSource = {
* If not provided, the `uri` is used also as the cache key.
*/
cacheKey?: string;
diff --git a/patches/expo-modules-core+2.2.3.patch b/patches/expo-modules-core+2.5.0.patch
similarity index 100%
rename from patches/expo-modules-core+2.2.3.patch
rename to patches/expo-modules-core+2.5.0.patch