feat(MM-65147): upgrade to react-native 0.77.3 (#9253)

* feat(MM-65147): upgrade to react-native 0.77.3
* basic iOS & Android changes
* patch packages
* react-native-network-client temporary until fix upstream
* local updates
* delete patch for react-native-network-client
* update react-native-network-client@1.9.0
* update RNN patch package to fix kotlin bug
* revert unneeded changes
* changes based on PR review
* ensure insert not happening if any of the values are null
* update watermelondb to 2.81.0
* update watermelon patch file name
* update secure-pdf-viewer to use latest lib
* fix typescript errors
* update podfile.lock
* update podfile.lock
* update podfile.lock again?
* podfile.lock update again
* temporarily update hermes engine
* temp
* fix alamo issue.
* revert changes to pod update
* pod update vs pod install
* remove cache for a bit
* revert the pod caching
* oops
* update podfile.lock again
* fix(MM-66825): dynamic patching of 16kb pagesize (#9361)
* fix(MM-66825): dynamic patching of 16kb pagesize
* fix lint and tsc errors
* add npx patch-package
* run patcing somewhere else instead, but this will break  iOS
* move reinstall around
* simplify script
* expo-image wasn't updating
* update caching restore key
* using git apply
* fix lint issues
* readme changes
* remove some wrong instructions
* remove redundant npx patch-package
* update build script
This commit is contained in:
Rahim Rahman 2025-12-22 07:35:38 -07:00 committed by GitHub
parent 3a4e7b6cd6
commit 522812e126
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 2311 additions and 1630 deletions

View file

@ -12,6 +12,13 @@ runs:
- name: ci/prepare-mobile-build - name: ci/prepare-mobile-build
uses: ./.github/actions/prepare-mobile-build uses: ./.github/actions/prepare-mobile-build
- name: ci/apply-16kb-pagesize-patch
shell: bash
run: |
echo "::group::Apply 16KB page size compatibility patch"
npm run apply-16kb-pagesize-patch
echo "::endgroup::"
- name: ci/setup-java - name: ci/setup-java
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:

View file

@ -45,10 +45,9 @@ runs:
path: | path: |
ios/Pods ios/Pods
libraries/@mattermost/intune/ios/Frameworks libraries/@mattermost/intune/ios/Frameworks
key: ${{ runner.os }}-pods-v3-intune-${{ inputs.intune-enabled }}-${{ steps.intune-hash.outputs.hash }}-${{ hashFiles('ios/Podfile.lock') }} key: ${{ runner.os }}-pods-v4-intune-${{ inputs.intune-enabled }}-${{ steps.intune-hash.outputs.hash }}-${{ hashFiles('ios/Podfile.lock') }}-${{ github.ref_name }}
restore-keys: | restore-keys: |
${{ runner.os }}-pods-v3-intune-${{ inputs.intune-enabled }}-${{ steps.intune-hash.outputs.hash }}- ${{ runner.os }}-pods-v4-intune-${{ inputs.intune-enabled }}-${{ steps.intune-hash.outputs.hash }}-${{ hashFiles('ios/Podfile.lock') }}-
${{ runner.os }}-pods-v3-intune-${{ inputs.intune-enabled }}-
- name: ci/install-pods-dependencies - name: ci/install-pods-dependencies
shell: bash shell: bash

View file

@ -12,6 +12,34 @@ We plan on releasing monthly updates with new features - check the [changelog](h
**Important:** If you self-compile the Mattermost Mobile apps you also need to deploy your own [Mattermost Push Notification Service](https://github.com/mattermost/mattermost-push-proxy/releases). **Important:** If you self-compile the Mattermost Mobile apps you also need to deploy your own [Mattermost Push Notification Service](https://github.com/mattermost/mattermost-push-proxy/releases).
# Android 16KB Page Size Support
**Temporary Requirement:** To comply with Google Play's 16KB page size requirement for Android devices, this project includes a compatibility patch that must be applied before building for Android.
### When to Apply the Patch
- **CI/CD Builds:** The patch is automatically applied in GitHub Actions for Android builds
- **Local Development:** If you're building Android locally and encounter 16KB page size related issues, run:
```bash
npm run apply-16kb-pagesize-patch
```
This script will:
1. Update package dependencies to compatible versions
2. Apply necessary code changes for 16KB page size support
3. Update patch files for modified dependencies
4. Regenerate `package-lock.json`
### ⚠️ Important Warnings
- **DO NOT commit the changes** applied by this patch to the repository
- **These changes will break iOS builds** if committed
- The patch is designed to be applied only during Android CI builds
- For local development, revert all changes after building Android
**Note:** This is a temporary solution until all dependencies natively support 16KB page sizes.
# How to Contribute # How to Contribute
### Testing ### Testing

View file

@ -135,7 +135,7 @@ class PushNotificationDataRunnable {
threadsArray.add(thread) threadsArray.add(thread)
} }
for(i in 0 until it.size()) { for(i in 0 until it.size()) {
val thread = it.getMap(i) it.getMap(i)?.let { thread ->
val threadId = thread.getString("id") val threadId = thread.getString("id")
if (threadId != null) { if (threadId != null) {
if (threadIds.contains(threadId)) { if (threadIds.contains(threadId)) {
@ -153,6 +153,7 @@ class PushNotificationDataRunnable {
} }
} }
} }
}
return threadsArray return threadsArray
} }

View file

@ -54,23 +54,26 @@ fun insertCategoriesWithChannels(db: WMDatabase, orderCategories: ReadableMap) {
val categories = orderCategories.getArray("categories") ?: return val categories = orderCategories.getArray("categories") ?: return
for (i in 0 until categories.size()) { for (i in 0 until categories.size()) {
val category = categories.getMap(i) val category = categories.getMap(i)
val id = category.getString("id") category?.let { cat ->
val teamId = category.getString("team_id") val id = cat.getString("id")
val channelIds = category.getArray("channel_ids") val teamId = cat.getString("team_id")
insertCategory(db, category) val channelIds = cat.getArray("channel_ids")
insertCategory(db, cat)
if (id != null && teamId != null) { if (id != null && teamId != null) {
channelIds?.let { insertCategoryChannels(db, id, teamId, it) } channelIds?.let { insertCategoryChannels(db, id, teamId, it) }
} }
} }
} }
}
fun insertChannelToDefaultCategory(db: WMDatabase, categoryChannels: ReadableArray) { fun insertChannelToDefaultCategory(db: WMDatabase, categoryChannels: ReadableArray) {
try { try {
for (i in 0 until categoryChannels.size()) { for (i in 0 until categoryChannels.size()) {
val cc = categoryChannels.getMap(i) categoryChannels.getMap(i)?.let { cc ->
val id = cc.getString("id") val id = cc.getString("id")
val categoryId = cc.getString("category_id") val categoryId = cc.getString("category_id")
val channelId = cc.getString("channel_id") val channelId = cc.getString("channel_id")
if (id != null && categoryId != null && channelId != null) {
val count = countByColumn(db, "CategoryChannel", "category_id", categoryId) val count = countByColumn(db, "CategoryChannel", "category_id", categoryId)
db.execute( db.execute(
""" """
@ -81,6 +84,8 @@ fun insertChannelToDefaultCategory(db: WMDatabase, categoryChannels: ReadableArr
arrayOf(id, categoryId, channelId, if (count > 0) count + 1 else count) arrayOf(id, categoryId, channelId, if (count > 0) count + 1 else count)
) )
} }
}
}
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }

View file

@ -26,7 +26,7 @@ internal fun DatabaseHelper.saveToDatabase(db: WMDatabase, data: ReadableMap, te
data.getArray("threads")?.let { data.getArray("threads")?.let {
val threadsArray = ArrayList<ReadableMap>() val threadsArray = ArrayList<ReadableMap>()
for (i in 0 until it.size()) { for (i in 0 until it.size()) {
threadsArray.add(it.getMap(i)) it.getMap(i)?.let { map -> threadsArray.add(map) }
} }
handleThreads(db, threadsArray, teamId) handleThreads(db, threadsArray, teamId)
} }

View file

@ -10,8 +10,10 @@ import com.nozbe.watermelondb.WMDatabase
internal fun findPostInChannel(chunks: ReadableArray, earliest: Double, latest: Double): ReadableMap? { internal fun findPostInChannel(chunks: ReadableArray, earliest: Double, latest: Double): ReadableMap? {
for (i in 0 until chunks.size()) { for (i in 0 until chunks.size()) {
val chunk = chunks.getMap(i) val chunk = chunks.getMap(i)
if (earliest >= chunk.getDouble("earliest") || latest <= chunk.getDouble("latest")) { chunk?.let {
return chunk if (earliest >= it.getDouble("earliest") || latest <= it.getDouble("latest")) {
return it
}
} }
} }
@ -45,10 +47,12 @@ internal fun mergePostsInChannel(db: WMDatabase, existingChunks: ReadableArray,
for (i in 0 until existingChunks.size()) { for (i in 0 until existingChunks.size()) {
try { try {
val chunk = existingChunks.getMap(i) val chunk = existingChunks.getMap(i)
if (newChunk.getDouble("earliest") <= chunk.getDouble("earliest") && chunk?.let {
newChunk.getDouble("latest") >= chunk.getDouble("latest")) { if (newChunk.getDouble("earliest") <= it.getDouble("earliest") &&
db.execute("DELETE FROM PostsInChannel WHERE id = ?", arrayOf(chunk.getString("id"))) newChunk.getDouble("latest") >= it.getDouble("latest")) {
break db.execute("DELETE FROM PostsInChannel WHERE id = ?", arrayOf(it.getString("id")))
return
}
} }
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()

View file

@ -83,6 +83,7 @@ internal fun insertThreadParticipants(db: WMDatabase, threadId: String, particip
for (i in 0 until participants.size()) { for (i in 0 until participants.size()) {
try { try {
val participant = participants.getMap(i) val participant = participants.getMap(i)
participant?.let {
val id = RandomId.generate() val id = RandomId.generate()
db.execute( db.execute(
""" """
@ -90,8 +91,9 @@ internal fun insertThreadParticipants(db: WMDatabase, threadId: String, particip
(id, thread_id, user_id, _changed, _status) (id, thread_id, user_id, _changed, _status)
VALUES (?, ?, ?, '', 'created') VALUES (?, ?, ?, '', 'created')
""".trimIndent(), """.trimIndent(),
arrayOf(id, threadId, participant.getString("id")) arrayOf(id, threadId, it.getString("id"))
) )
}
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }

View file

@ -48,14 +48,15 @@ fun getCurrentUserLocale(db: WMDatabase): String {
fun handleUsers(db: WMDatabase, users: ReadableArray) { fun handleUsers(db: WMDatabase, users: ReadableArray) {
for (i in 0 until users.size()) { for (i in 0 until users.size()) {
val user = users.getMap(i) val user = users.getMap(i)
val roles = user.getString("roles") ?: "" user?.let { u ->
val roles = u.getString("roles") ?: ""
val isBot = try { val isBot = try {
user.getBoolean("is_bot") u.getBoolean("is_bot")
} catch (e: NoSuchKeyException) { } catch (e: NoSuchKeyException) {
false false
} }
val lastPictureUpdate = try { user.getDouble("last_picture_update") } catch (e: NoSuchKeyException) { 0 } val lastPictureUpdate = try { u.getDouble("last_picture_update") } catch (e: NoSuchKeyException) { 0 }
try { try {
db.execute( db.execute(
@ -66,15 +67,15 @@ fun handleUsers(db: WMDatabase, users: ReadableArray) {
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '', 'created') VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '', 'created')
""".trimIndent(), """.trimIndent(),
arrayOf( arrayOf(
user.getString("id"), u.getString("id"),
user.getString("auth_service"), user.getDouble("update_at"), user.getDouble("delete_at"), u.getString("auth_service"), u.getDouble("update_at"), u.getDouble("delete_at"),
user.getString("email"), user.getString("first_name"), isBot, u.getString("email"), u.getString("first_name"), isBot,
roles.contains("system_guest"), user.getString("last_name"), lastPictureUpdate, roles.contains("system_guest"), u.getString("last_name"), lastPictureUpdate,
user.getString("locale"), user.getString("nickname"), user.getString("position"), u.getString("locale"), u.getString("nickname"), u.getString("position"),
roles, "", user.getString("username"), "{}", roles, "", u.getString("username"), "{}",
ReadableMapUtils.toJSONObject(user.getMap("props") ReadableMapUtils.toJSONObject(u.getMap("props")
?: Arguments.createMap()).toString(), ?: Arguments.createMap()).toString(),
ReadableMapUtils.toJSONObject(user.getMap("timezone") ReadableMapUtils.toJSONObject(u.getMap("timezone")
?: Arguments.createMap()).toString(), ?: Arguments.createMap()).toString(),
) )
) )
@ -83,3 +84,4 @@ fun handleUsers(db: WMDatabase, users: ReadableArray) {
} }
} }
} }
}

View file

@ -26,13 +26,15 @@ suspend fun PushNotificationDataRunnable.Companion.fetchMyChannel(db: WMDatabase
"D" -> { "D" -> {
profilesArray = fetchProfileInChannel(db, serverUrl, channelId) profilesArray = fetchProfileInChannel(db, serverUrl, channelId)
if ((profilesArray?.size() ?: 0) > 0) { if ((profilesArray?.size() ?: 0) > 0) {
val displayName = displayUsername(profilesArray!!.getMap(0), displayNameSetting) profilesArray?.getMap(0)?.let { profile ->
val displayName = displayUsername(profile, displayNameSetting)
val data = Arguments.createMap() val data = Arguments.createMap()
data.merge(channelData) data.merge(channelData)
data.putString("display_name", displayName) data.putString("display_name", displayName)
channelData = data channelData = data
} }
} }
}
"G" -> { "G" -> {
profilesArray = fetchProfileInChannel(db, serverUrl, channelId) profilesArray = fetchProfileInChannel(db, serverUrl, channelId)
if ((profilesArray?.size() ?: 0) > 0) { if ((profilesArray?.size() ?: 0) > 0) {
@ -117,8 +119,10 @@ private suspend fun PushNotificationDataRunnable.Companion.fetchProfileInChannel
if (profilesArray != null) { if (profilesArray != null) {
for (i in 0 until profilesArray.size()) { for (i in 0 until profilesArray.size()) {
val profile = profilesArray.getMap(i) val profile = profilesArray.getMap(i)
if (profile.getString("id") != currentUserId) { profile?.let {
result.pushMap(profile) if (it.getString("id") != currentUserId) {
result.pushMap(it)
}
} }
} }
} }
@ -152,7 +156,9 @@ private fun PushNotificationDataRunnable.Companion.displayGroupMessageName(profi
val names = ArrayList<String>() val names = ArrayList<String>()
for (i in 0 until profilesArray.size()) { for (i in 0 until profilesArray.size()) {
val profile = profilesArray.getMap(i) val profile = profilesArray.getMap(i)
names.add(displayUsername(profile, displayNameSetting)) profile?.let {
names.add(displayUsername(it, displayNameSetting))
}
} }
return names.sortedWith { s1, s2 -> return names.sortedWith { s1, s2 ->

View file

@ -62,7 +62,7 @@ internal suspend fun PushNotificationDataRunnable.Companion.fetchPosts(
val userIdsAlreadyLoaded = mutableListOf<String>() val userIdsAlreadyLoaded = mutableListOf<String>()
if (loadedProfiles != null) { if (loadedProfiles != null) {
for (i in 0 until loadedProfiles.size()) { for (i in 0 until loadedProfiles.size()) {
loadedProfiles.getMap(i).getString("id")?.let { userIdsAlreadyLoaded.add(it) } loadedProfiles.getMap(i)?.getString("id")?.let { userIdsAlreadyLoaded.add(it) }
} }
} }
@ -95,12 +95,14 @@ internal suspend fun PushNotificationDataRunnable.Companion.fetchPosts(
if (attachments != null) { if (attachments != null) {
for (i in 0 until attachments.size()) { for (i in 0 until attachments.size()) {
val attachment = attachments.getMap(i) val attachment = attachments.getMap(i)
val pretext = attachment.getString("pretext") attachment?.let {
val text = attachment.getString("text") val pretext = it.getString("pretext")
val text = it.getString("text")
findNeededUsernames(pretext) findNeededUsernames(pretext)
findNeededUsernames(text) findNeededUsernames(text)
} }
} }
}
if (isCRTEnabled) { if (isCRTEnabled) {
@ -132,19 +134,19 @@ internal suspend fun PushNotificationDataRunnable.Companion.fetchPosts(
participants?.let { participants?.let {
for (i in 0 until it.size()) { for (i in 0 until it.size()) {
val participant = it.getMap(i) val participant = it.getMap(i)
participant?.let { p ->
val participantId = participant.getString("id") val participantId = p.getString("id")
if (participantId != currentUserId && participantId != null) { if (participantId != currentUserId && participantId != null) {
if (!threadParticipantUserIds.contains(participantId) && !userIdsAlreadyLoaded.contains(participantId)) { if (!threadParticipantUserIds.contains(participantId) && !userIdsAlreadyLoaded.contains(participantId)) {
threadParticipantUserIds.add(participantId) threadParticipantUserIds.add(participantId)
} }
if (!threadParticipantUsers.containsKey(participantId)) { if (!threadParticipantUsers.containsKey(participantId)) {
threadParticipantUsers[participantId] = participant threadParticipantUsers[participantId] = p
} }
} }
val username = participant.getString("username") val username = p.getString("username")
if (username != null && username != currentUsername && !threadParticipantUsernames.contains(username)) { if (username != null && username != currentUsername && !threadParticipantUsernames.contains(username)) {
threadParticipantUsernames.add(username) threadParticipantUsernames.add(username)
} }
@ -152,6 +154,7 @@ internal suspend fun PushNotificationDataRunnable.Companion.fetchPosts(
} }
} }
} }
}
val existingUserIds = queryIds(db, "User", userIds.toTypedArray()) val existingUserIds = queryIds(db, "User", userIds.toTypedArray())
val existingUsernames = queryByColumn(db, "User", "username", usernames.toTypedArray()) val existingUsernames = queryByColumn(db, "User", "username", usernames.toTypedArray())

View file

@ -56,6 +56,6 @@ internal suspend fun PushNotificationDataRunnable.Companion.fetchNeededUsers(ser
internal fun PushNotificationDataRunnable.Companion.addUsersToList(users: ReadableArray, list: ArrayList<Any>) { internal fun PushNotificationDataRunnable.Companion.addUsersToList(users: ReadableArray, list: ArrayList<Any>) {
for (i in 0 until users.size()) { for (i in 0 until users.size()) {
list.add(users.getMap(i)) users.getMap(i)?.let { list.add(it) }
} }
} }

View file

@ -5,11 +5,11 @@ buildscript {
compileSdkVersion = 35 compileSdkVersion = 35
targetSdkVersion = 35 targetSdkVersion = 35
supportLibVersion = "35.0.0" supportLibVersion = "35.0.0"
kotlinVersion = "1.9.25" kotlinVersion = "2.0.21"
kotlin_version = kotlinVersion kotlin_version = kotlinVersion
RNNKotlinVersion = kotlinVersion RNNKotlinVersion = kotlinVersion
firebaseVersion = "24.1.0" firebaseVersion = "24.1.0"
ndkVersion = "26.1.10909125" ndkVersion = "27.1.12297006"
} }
repositories { repositories {
mavenCentral() mavenCentral()

View file

@ -1,49 +1,50 @@
# This is a Gradle generated file for dependency locking. # This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised. # Manual edits can break the build and are not advised.
# This file is expected to be part of source control. # This file is expected to be part of source control.
androidx.databinding:databinding-common:8.6.0=classpath androidx.databinding:databinding-common:8.7.2=classpath
androidx.databinding:databinding-compiler-common:8.6.0=classpath androidx.databinding:databinding-compiler-common:8.7.2=classpath
com.android.databinding:baseLibrary:8.6.0=classpath com.android.databinding:baseLibrary:8.7.2=classpath
com.android.tools.analytics-library:crash:31.6.0=classpath com.android.tools.analytics-library:crash:31.7.2=classpath
com.android.tools.analytics-library:protos:31.6.0=classpath com.android.tools.analytics-library:protos:31.7.2=classpath
com.android.tools.analytics-library:shared:31.6.0=classpath com.android.tools.analytics-library:shared:31.7.2=classpath
com.android.tools.analytics-library:tracker:31.6.0=classpath com.android.tools.analytics-library:tracker:31.7.2=classpath
com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
com.android.tools.build:aapt2-proto:8.6.0-11315950=classpath com.android.tools.build:aapt2-proto:8.7.2-12006047=classpath
com.android.tools.build:aaptcompiler:8.6.0=classpath com.android.tools.build:aaptcompiler:8.7.2=classpath
com.android.tools.build:apksig:8.6.0=classpath com.android.tools.build:apksig:8.7.2=classpath
com.android.tools.build:apkzlib:8.6.0=classpath com.android.tools.build:apkzlib:8.7.2=classpath
com.android.tools.build:builder-model:8.6.0=classpath com.android.tools.build:builder-model:8.7.2=classpath
com.android.tools.build:builder-test-api:8.6.0=classpath com.android.tools.build:builder-test-api:8.7.2=classpath
com.android.tools.build:builder:8.6.0=classpath com.android.tools.build:builder:8.7.2=classpath
com.android.tools.build:bundletool:1.16.0=classpath com.android.tools.build:bundletool:1.17.1=classpath
com.android.tools.build:gradle-api:8.6.0=classpath com.android.tools.build:gradle-api:8.7.2=classpath
com.android.tools.build:gradle-settings-api:8.6.0=classpath com.android.tools.build:gradle-settings-api:8.7.2=classpath
com.android.tools.build:gradle:8.6.0=classpath com.android.tools.build:gradle:8.7.2=classpath
com.android.tools.build:manifest-merger:31.6.0=classpath com.android.tools.build:manifest-merger:31.7.2=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
com.android.tools.ddms:ddmlib:31.6.0=classpath com.android.tools.ddms:ddmlib:31.7.2=classpath
com.android.tools.layoutlib:layoutlib-api:31.6.0=classpath com.android.tools.layoutlib:layoutlib-api:31.7.2=classpath
com.android.tools.lint:lint-model:31.6.0=classpath com.android.tools.lint:lint-model:31.7.2=classpath
com.android.tools.lint:lint-typedef-remover:31.6.0=classpath com.android.tools.lint:lint-typedef-remover:31.7.2=classpath
com.android.tools.utp:android-device-provider-ddmlib-proto:31.6.0=classpath com.android.tools.utp:android-device-provider-ddmlib-proto:31.7.2=classpath
com.android.tools.utp:android-device-provider-gradle-proto:31.6.0=classpath com.android.tools.utp:android-device-provider-gradle-proto:31.7.2=classpath
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.6.0=classpath com.android.tools.utp:android-device-provider-profile-proto:31.7.2=classpath
com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.6.0=classpath com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.7.2=classpath
com.android.tools.utp:android-test-plugin-host-coverage-proto:31.6.0=classpath com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.7.2=classpath
com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.6.0=classpath com.android.tools.utp:android-test-plugin-host-coverage-proto:31.7.2=classpath
com.android.tools.utp:android-test-plugin-host-logcat-proto:31.6.0=classpath com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.7.2=classpath
com.android.tools.utp:android-test-plugin-host-retention-proto:31.6.0=classpath com.android.tools.utp:android-test-plugin-host-logcat-proto:31.7.2=classpath
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.6.0=classpath com.android.tools.utp:android-test-plugin-host-retention-proto:31.7.2=classpath
com.android.tools:annotations:31.6.0=classpath com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.7.2=classpath
com.android.tools:common:31.6.0=classpath com.android.tools:annotations:31.7.2=classpath
com.android.tools:dvlib:31.6.0=classpath com.android.tools:common:31.7.2=classpath
com.android.tools:repository:31.6.0=classpath com.android.tools:dvlib:31.7.2=classpath
com.android.tools:sdk-common:31.6.0=classpath com.android.tools:repository:31.7.2=classpath
com.android.tools:sdklib:31.6.0=classpath com.android.tools:sdk-common:31.7.2=classpath
com.android:signflinger:8.6.0=classpath com.android.tools:sdklib:31.7.2=classpath
com.android:zipflinger:8.6.0=classpath com.android:signflinger:8.7.2=classpath
com.android:zipflinger:8.7.2=classpath
com.google.android.gms:strict-version-matcher-plugin:1.2.4=classpath com.google.android.gms:strict-version-matcher-plugin:1.2.4=classpath
com.google.android:annotations:4.1.1.4=classpath com.google.android:annotations:4.1.1.4=classpath
com.google.api.grpc:proto-google-common-protos:2.17.0=classpath com.google.api.grpc:proto-google-common-protos:2.17.0=classpath
@ -113,34 +114,29 @@ org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
org.glassfish.jaxb:txw2:2.3.2=classpath org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath org.jdom:jdom2:2.0.6=classpath
org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
org.jetbrains.kotlin:kotlin-android-extensions:1.9.25=classpath org.jetbrains.kotlin:kotlin-build-statistics:2.0.21=classpath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.25=classpath org.jetbrains.kotlin:kotlin-build-tools-api:2.0.21=classpath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.25=classpath org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.21=classpath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.25=classpath org.jetbrains.kotlin:kotlin-compiler-runner:2.0.21=classpath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.25=classpath org.jetbrains.kotlin:kotlin-daemon-client:2.0.21=classpath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.25=classpath org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.25=classpath org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:2.0.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.25=classpath org.jetbrains.kotlin:kotlin-gradle-plugin-api:2.0.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.25=classpath org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:2.0.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.25=classpath org.jetbrains.kotlin:kotlin-gradle-plugin-idea:2.0.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.25=classpath org.jetbrains.kotlin:kotlin-gradle-plugin-model:2.0.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.25=classpath org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.21=classpath
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.25=classpath org.jetbrains.kotlin:kotlin-gradle-plugins-bom:2.0.21=classpath
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.25=classpath org.jetbrains.kotlin:kotlin-klib-commonizer-api:2.0.21=classpath
org.jetbrains.kotlin:kotlin-native-utils:1.9.25=classpath org.jetbrains.kotlin:kotlin-native-utils:2.0.21=classpath
org.jetbrains.kotlin:kotlin-project-model:1.9.25=classpath
org.jetbrains.kotlin:kotlin-reflect:1.9.20=classpath org.jetbrains.kotlin:kotlin-reflect:1.9.20=classpath
org.jetbrains.kotlin:kotlin-scripting-common:1.9.25=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.25=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.25=classpath
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.25=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.20=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-jdk8:1.9.20=classpath
org.jetbrains.kotlin:kotlin-stdlib:1.9.25=classpath org.jetbrains.kotlin:kotlin-stdlib:2.0.21=classpath
org.jetbrains.kotlin:kotlin-tooling-core:1.9.25=classpath org.jetbrains.kotlin:kotlin-tooling-core:2.0.21=classpath
org.jetbrains.kotlin:kotlin-util-io:1.9.25=classpath org.jetbrains.kotlin:kotlin-util-io:2.0.21=classpath
org.jetbrains.kotlin:kotlin-util-klib:1.9.25=classpath org.jetbrains.kotlin:kotlin-util-klib:2.0.21=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=classpath
org.jetbrains:annotations:23.0.0=classpath org.jetbrains:annotations:23.0.0=classpath
org.jvnet.staxex:stax-ex:1.8.1=classpath org.jvnet.staxex:stax-ex:1.8.1=classpath
org.ow2.asm:asm-analysis:9.6=classpath org.ow2.asm:asm-analysis:9.6=classpath

View file

@ -79,9 +79,6 @@ function ScheduledPostIndicator({
); );
return ( return (
<View
className='ScheduledPostIndicator'
>
<View style={styles.container}> <View style={styles.container}>
<CompassIcon <CompassIcon
color={changeOpacity(theme.centerChannelColor, 0.6)} color={changeOpacity(theme.centerChannelColor, 0.6)}
@ -105,7 +102,6 @@ function ScheduledPostIndicator({
</Text> </Text>
</Text> </Text>
</View> </View>
</View>
); );
} }

View file

@ -12,12 +12,11 @@
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
1AC06461F0B9867B11829943 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24C9C33C1C823BB8E1B3E161 /* ExpoModulesProvider.swift */; }; 1AC06461F0B9867B11829943 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24C9C33C1C823BB8E1B3E161 /* ExpoModulesProvider.swift */; };
266E7D53748BB8A1308B5CF2 /* libPods-MattermostShare.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B1BD2D4C53C3682D8892612F /* libPods-MattermostShare.a */; };
27C667A9295241B600E590D5 /* Sentry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27C667A8295241B600E590D5 /* Sentry.swift */; }; 27C667A9295241B600E590D5 /* Sentry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27C667A8295241B600E590D5 /* Sentry.swift */; };
27C667AA295241B600E590D5 /* Sentry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27C667A8295241B600E590D5 /* Sentry.swift */; }; 27C667AA295241B600E590D5 /* Sentry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27C667A8295241B600E590D5 /* Sentry.swift */; };
413A0FD06EA0DB2B3F30403F /* libPods-NotificationService.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AEDDC97F55A1F6C056C6B1BC /* libPods-NotificationService.a */; };
536CC6C323E79287002C478C /* RNNotificationEventHandler+HandleReplyAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 536CC6C123E79287002C478C /* RNNotificationEventHandler+HandleReplyAction.m */; }; 536CC6C323E79287002C478C /* RNNotificationEventHandler+HandleReplyAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 536CC6C123E79287002C478C /* RNNotificationEventHandler+HandleReplyAction.m */; };
58495E36BF1A4EAB93609E57 /* Metropolis-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 54956DEFEBB74EF78C3A6AE5 /* Metropolis-SemiBold.ttf */; }; 58495E36BF1A4EAB93609E57 /* Metropolis-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 54956DEFEBB74EF78C3A6AE5 /* Metropolis-SemiBold.ttf */; };
63A22C643F2AC11D1F536FFD /* Pods_NotificationService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 482CD108BF5FC3AC64EB73F4 /* Pods_NotificationService.framework */; };
672D988829F1927F004228D6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 672D984629F1927E004228D6 /* InfoPlist.strings */; }; 672D988829F1927F004228D6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 672D984629F1927E004228D6 /* InfoPlist.strings */; };
672D988A29F1927F004228D6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 672D984929F1927E004228D6 /* InfoPlist.strings */; }; 672D988A29F1927F004228D6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 672D984929F1927E004228D6 /* InfoPlist.strings */; };
672D988C29F1927F004228D6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 672D984C29F1927E004228D6 /* InfoPlist.strings */; }; 672D988C29F1927F004228D6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 672D984C29F1927E004228D6 /* InfoPlist.strings */; };
@ -170,11 +169,12 @@
83ABFD132C1C90D90029685B /* calls_cheerful.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 83ABFD0F2C1C90D90029685B /* calls_cheerful.mp3 */; }; 83ABFD132C1C90D90029685B /* calls_cheerful.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 83ABFD0F2C1C90D90029685B /* calls_cheerful.mp3 */; };
83ABFD142C1C90D90029685B /* calls_calm.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 83ABFD102C1C90D90029685B /* calls_calm.mp3 */; }; 83ABFD142C1C90D90029685B /* calls_calm.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 83ABFD102C1C90D90029685B /* calls_calm.mp3 */; };
83ABFD152C1C90D90029685B /* calls_urgent.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 83ABFD112C1C90D90029685B /* calls_urgent.mp3 */; }; 83ABFD152C1C90D90029685B /* calls_urgent.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 83ABFD112C1C90D90029685B /* calls_urgent.mp3 */; };
A8404C71A72745D3D79CF299 /* Pods_MattermostShare.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 46F51987161143CBA45CB13A /* Pods_MattermostShare.framework */; };
A94508A396424B2DB778AFE9 /* OpenSans-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E5C16B14E1CE4868886A1A00 /* OpenSans-SemiBold.ttf */; }; A94508A396424B2DB778AFE9 /* OpenSans-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E5C16B14E1CE4868886A1A00 /* OpenSans-SemiBold.ttf */; };
C84AE74C57DDE97D6C3D6924 /* libPods-Mattermost.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A83BBA09DE89A630126EA06 /* libPods-Mattermost.a */; };
C9A107102BBD7C8700753CDC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = C9A1070F2BBD7C8700753CDC /* PrivacyInfo.xcprivacy */; }; C9A107102BBD7C8700753CDC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = C9A1070F2BBD7C8700753CDC /* PrivacyInfo.xcprivacy */; };
C9A107122BBDA00200753CDC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = C9A107112BBDA00200753CDC /* PrivacyInfo.xcprivacy */; }; C9A107122BBDA00200753CDC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = C9A107112BBDA00200753CDC /* PrivacyInfo.xcprivacy */; };
C9A107142BBDBC8F00753CDC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = C9A107132BBDBC8F00753CDC /* PrivacyInfo.xcprivacy */; }; C9A107142BBDBC8F00753CDC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = C9A107132BBDBC8F00753CDC /* PrivacyInfo.xcprivacy */; };
EC5A74C9C7BE208EB8ECA076 /* Pods_Mattermost.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FA24657E0EE0B2378EFED0E /* Pods_Mattermost.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -229,13 +229,16 @@
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Mattermost/Images.xcassets; sourceTree = "<group>"; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Mattermost/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Mattermost/Info.plist; sourceTree = "<group>"; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Mattermost/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Mattermost/main.m; sourceTree = "<group>"; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Mattermost/main.m; sourceTree = "<group>"; };
1FA24657E0EE0B2378EFED0E /* Pods_Mattermost.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mattermost.framework; sourceTree = BUILT_PRODUCTS_DIR; };
24C9C33C1C823BB8E1B3E161 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-Mattermost/ExpoModulesProvider.swift"; sourceTree = "<group>"; }; 24C9C33C1C823BB8E1B3E161 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-Mattermost/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
27C667A8295241B600E590D5 /* Sentry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sentry.swift; sourceTree = "<group>"; }; 27C667A8295241B600E590D5 /* Sentry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sentry.swift; sourceTree = "<group>"; };
2E17B88EAD6181B9E9A24084 /* Pods-Mattermost.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mattermost.debug.xcconfig"; path = "Target Support Files/Pods-Mattermost/Pods-Mattermost.debug.xcconfig"; sourceTree = "<group>"; }; 2E17B88EAD6181B9E9A24084 /* Pods-Mattermost.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mattermost.debug.xcconfig"; path = "Target Support Files/Pods-Mattermost/Pods-Mattermost.debug.xcconfig"; sourceTree = "<group>"; };
32AC3D4EA79E44738A6E9766 /* OpenSans-BoldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-BoldItalic.ttf"; path = "../assets/fonts/OpenSans-BoldItalic.ttf"; sourceTree = "<group>"; }; 32AC3D4EA79E44738A6E9766 /* OpenSans-BoldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-BoldItalic.ttf"; path = "../assets/fonts/OpenSans-BoldItalic.ttf"; sourceTree = "<group>"; };
3647DF63D6764CF093375861 /* OpenSans-ExtraBold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-ExtraBold.ttf"; path = "../assets/fonts/OpenSans-ExtraBold.ttf"; sourceTree = "<group>"; }; 3647DF63D6764CF093375861 /* OpenSans-ExtraBold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-ExtraBold.ttf"; path = "../assets/fonts/OpenSans-ExtraBold.ttf"; sourceTree = "<group>"; };
41F3AFE83AAF4B74878AB78A /* OpenSans-Italic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Italic.ttf"; path = "../assets/fonts/OpenSans-Italic.ttf"; sourceTree = "<group>"; }; 41F3AFE83AAF4B74878AB78A /* OpenSans-Italic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Italic.ttf"; path = "../assets/fonts/OpenSans-Italic.ttf"; sourceTree = "<group>"; };
46F51987161143CBA45CB13A /* Pods_MattermostShare.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MattermostShare.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4751361789DCCAD0DBD95C16 /* Pods-MattermostShare.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MattermostShare.debug.xcconfig"; path = "Target Support Files/Pods-MattermostShare/Pods-MattermostShare.debug.xcconfig"; sourceTree = "<group>"; }; 4751361789DCCAD0DBD95C16 /* Pods-MattermostShare.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MattermostShare.debug.xcconfig"; path = "Target Support Files/Pods-MattermostShare/Pods-MattermostShare.debug.xcconfig"; sourceTree = "<group>"; };
482CD108BF5FC3AC64EB73F4 /* Pods_NotificationService.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NotificationService.framework; sourceTree = BUILT_PRODUCTS_DIR; };
495BC95F23565ABF00C40C83 /* libXCDYouTubeKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libXCDYouTubeKit.a; sourceTree = BUILT_PRODUCTS_DIR; }; 495BC95F23565ABF00C40C83 /* libXCDYouTubeKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libXCDYouTubeKit.a; sourceTree = BUILT_PRODUCTS_DIR; };
495BC96123565ADD00C40C83 /* libYoutubePlayer-in-WKWebView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = "libYoutubePlayer-in-WKWebView.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 495BC96123565ADD00C40C83 /* libYoutubePlayer-in-WKWebView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = "libYoutubePlayer-in-WKWebView.a"; sourceTree = BUILT_PRODUCTS_DIR; };
499F7B3F235513F600E7AF6E /* libXCDYouTubeKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libXCDYouTubeKit.a; sourceTree = BUILT_PRODUCTS_DIR; }; 499F7B3F235513F600E7AF6E /* libXCDYouTubeKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libXCDYouTubeKit.a; sourceTree = BUILT_PRODUCTS_DIR; };
@ -293,7 +296,6 @@
67FEAE272A1261A000DDF4AE /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = Localizable.strings; sourceTree = "<group>"; }; 67FEAE272A1261A000DDF4AE /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = Localizable.strings; sourceTree = "<group>"; };
67FEAE2B2A127C3600DDF4AE /* NumberFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberFormatter.swift; sourceTree = "<group>"; }; 67FEAE2B2A127C3600DDF4AE /* NumberFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberFormatter.swift; sourceTree = "<group>"; };
6BAF8296411D4657B5A0E8F8 /* libRNReactNativeDocViewer.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNReactNativeDocViewer.a; sourceTree = "<group>"; }; 6BAF8296411D4657B5A0E8F8 /* libRNReactNativeDocViewer.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNReactNativeDocViewer.a; sourceTree = "<group>"; };
7A83BBA09DE89A630126EA06 /* libPods-Mattermost.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Mattermost.a"; sourceTree = BUILT_PRODUCTS_DIR; };
7F0F4B0924BA173900E14C60 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = SplashScreenResource/LaunchScreen.storyboard; sourceTree = "<group>"; }; 7F0F4B0924BA173900E14C60 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = SplashScreenResource/LaunchScreen.storyboard; sourceTree = "<group>"; };
7F151D3D221B062700FAD8F3 /* RuntimeUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuntimeUtils.swift; sourceTree = "<group>"; }; 7F151D3D221B062700FAD8F3 /* RuntimeUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuntimeUtils.swift; sourceTree = "<group>"; };
7F151D43221B082A00FAD8F3 /* Mattermost-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Mattermost-Bridging-Header.h"; path = "Mattermost/Mattermost-Bridging-Header.h"; sourceTree = "<group>"; }; 7F151D43221B082A00FAD8F3 /* Mattermost-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Mattermost-Bridging-Header.h"; path = "Mattermost/Mattermost-Bridging-Header.h"; sourceTree = "<group>"; };
@ -377,8 +379,6 @@
83ABFD102C1C90D90029685B /* calls_calm.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = calls_calm.mp3; path = ../assets/sounds/calls_calm.mp3; sourceTree = "<group>"; }; 83ABFD102C1C90D90029685B /* calls_calm.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = calls_calm.mp3; path = ../assets/sounds/calls_calm.mp3; sourceTree = "<group>"; };
83ABFD112C1C90D90029685B /* calls_urgent.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = calls_urgent.mp3; path = ../assets/sounds/calls_urgent.mp3; sourceTree = "<group>"; }; 83ABFD112C1C90D90029685B /* calls_urgent.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = calls_urgent.mp3; path = ../assets/sounds/calls_urgent.mp3; sourceTree = "<group>"; };
A10297DBBE728B2BF1BC045E /* Pods-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.debug.xcconfig"; sourceTree = "<group>"; }; A10297DBBE728B2BF1BC045E /* Pods-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.debug.xcconfig"; sourceTree = "<group>"; };
AEDDC97F55A1F6C056C6B1BC /* libPods-NotificationService.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NotificationService.a"; sourceTree = BUILT_PRODUCTS_DIR; };
B1BD2D4C53C3682D8892612F /* libPods-MattermostShare.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MattermostShare.a"; sourceTree = BUILT_PRODUCTS_DIR; };
BC977883E2624E05975CA65B /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Regular.ttf"; path = "../assets/fonts/OpenSans-Regular.ttf"; sourceTree = "<group>"; }; BC977883E2624E05975CA65B /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Regular.ttf"; path = "../assets/fonts/OpenSans-Regular.ttf"; sourceTree = "<group>"; };
BE17F630DB5D41FD93F32D22 /* OpenSans-LightItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-LightItalic.ttf"; path = "../assets/fonts/OpenSans-LightItalic.ttf"; sourceTree = "<group>"; }; BE17F630DB5D41FD93F32D22 /* OpenSans-LightItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-LightItalic.ttf"; path = "../assets/fonts/OpenSans-LightItalic.ttf"; sourceTree = "<group>"; };
C7E622B6B1B605983E8E23B7 /* Pods-MattermostShare.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MattermostShare.release.xcconfig"; path = "Target Support Files/Pods-MattermostShare/Pods-MattermostShare.release.xcconfig"; sourceTree = "<group>"; }; C7E622B6B1B605983E8E23B7 /* Pods-MattermostShare.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MattermostShare.release.xcconfig"; path = "Target Support Files/Pods-MattermostShare/Pods-MattermostShare.release.xcconfig"; sourceTree = "<group>"; };
@ -397,7 +397,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
C84AE74C57DDE97D6C3D6924 /* libPods-Mattermost.a in Frameworks */, EC5A74C9C7BE208EB8ECA076 /* Pods_Mattermost.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -405,7 +405,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
413A0FD06EA0DB2B3F30403F /* libPods-NotificationService.a in Frameworks */, 63A22C643F2AC11D1F536FFD /* Pods_NotificationService.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -413,7 +413,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
266E7D53748BB8A1308B5CF2 /* libPods-MattermostShare.a in Frameworks */, A8404C71A72745D3D79CF299 /* Pods_MattermostShare.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -562,9 +562,9 @@
7FFE32BF1FD9CCAA0038C7A0 /* Sentry.framework */, 7FFE32BF1FD9CCAA0038C7A0 /* Sentry.framework */,
7F43D6051F6BF9EB001FC614 /* libPods-Mattermost.a */, 7F43D6051F6BF9EB001FC614 /* libPods-Mattermost.a */,
81061F4CBB31484A94D5A8EE /* libz.tbd */, 81061F4CBB31484A94D5A8EE /* libz.tbd */,
7A83BBA09DE89A630126EA06 /* libPods-Mattermost.a */, 1FA24657E0EE0B2378EFED0E /* Pods_Mattermost.framework */,
AEDDC97F55A1F6C056C6B1BC /* libPods-NotificationService.a */, 46F51987161143CBA45CB13A /* Pods_MattermostShare.framework */,
B1BD2D4C53C3682D8892612F /* libPods-MattermostShare.a */, 482CD108BF5FC3AC64EB73F4 /* Pods_NotificationService.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1073,8 +1073,6 @@
7FC5698F28563FDB000B0905 /* PBXTargetDependency */, 7FC5698F28563FDB000B0905 /* PBXTargetDependency */,
); );
name = Mattermost; name = Mattermost;
packageProductDependencies = (
);
productName = "Hello World"; productName = "Hello World";
productReference = 13B07F961A680F5B00A75B9A /* Mattermost.app */; productReference = 13B07F961A680F5B00A75B9A /* Mattermost.app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
@ -1094,8 +1092,6 @@
dependencies = ( dependencies = (
); );
name = NotificationService; name = NotificationService;
packageProductDependencies = (
);
productName = NotificationService; productName = NotificationService;
productReference = 7F581D32221ED5C60099E66B /* NotificationService.appex */; productReference = 7F581D32221ED5C60099E66B /* NotificationService.appex */;
productType = "com.apple.product-type.app-extension"; productType = "com.apple.product-type.app-extension";
@ -1115,8 +1111,6 @@
dependencies = ( dependencies = (
); );
name = MattermostShare; name = MattermostShare;
packageProductDependencies = (
);
productName = MattermostShare; productName = MattermostShare;
productReference = 7FC5698628563FDB000B0905 /* MattermostShare.appex */; productReference = 7FC5698628563FDB000B0905 /* MattermostShare.appex */;
productType = "com.apple.product-type.app-extension"; productType = "com.apple.product-type.app-extension";
@ -1198,8 +1192,6 @@
uk, uk,
); );
mainGroup = 83CBB9F61A601CBA00E9B192; mainGroup = 83CBB9F61A601CBA00E9B192;
packageReferences = (
);
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
@ -2159,6 +2151,8 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = A10297DBBE728B2BF1BC045E /* Pods-NotificationService.debug.xcconfig */; baseConfigurationReference = A10297DBBE728B2BF1BC045E /* Pods-NotificationService.debug.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "$(inherited)"; CLANG_CXX_LANGUAGE_STANDARD = "$(inherited)";
@ -2208,6 +2202,8 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = FF7D3AE3E5E892576497A111 /* Pods-NotificationService.release.xcconfig */; baseConfigurationReference = FF7D3AE3E5E892576497A111 /* Pods-NotificationService.release.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "$(inherited)"; CLANG_CXX_LANGUAGE_STANDARD = "$(inherited)";
@ -2254,6 +2250,8 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 4751361789DCCAD0DBD95C16 /* Pods-MattermostShare.debug.xcconfig */; baseConfigurationReference = 4751361789DCCAD0DBD95C16 /* Pods-MattermostShare.debug.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "$(inherited)"; CLANG_CXX_LANGUAGE_STANDARD = "$(inherited)";
@ -2304,6 +2302,8 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = C7E622B6B1B605983E8E23B7 /* Pods-MattermostShare.release.xcconfig */; baseConfigurationReference = C7E622B6B1B605983E8E23B7 /* Pods-MattermostShare.release.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "$(inherited)"; CLANG_CXX_LANGUAGE_STANDARD = "$(inherited)";
@ -2392,6 +2392,17 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(inherited)",
"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers",
"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core",
"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon-Samples/ReactCommon_Samples.framework/Headers",
"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon-Samples/ReactCommon_Samples.framework/Headers/platform/ios",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers/react/renderer/components/view/platform/cxx",
"${PODS_CONFIGURATION_BUILD_DIR}/React-NativeModulesApple/React_NativeModulesApple.framework/Headers",
"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers",
"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios",
);
IPHONEOS_DEPLOYMENT_TARGET = 13.4; IPHONEOS_DEPLOYMENT_TARGET = 13.4;
LD = ""; LD = "";
LDPLUSPLUS = ""; LDPLUSPLUS = "";
@ -2455,7 +2466,16 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = (
"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers",
"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core",
"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon-Samples/ReactCommon_Samples.framework/Headers",
"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon-Samples/ReactCommon_Samples.framework/Headers/platform/ios",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers/react/renderer/components/view/platform/cxx",
"${PODS_CONFIGURATION_BUILD_DIR}/React-NativeModulesApple/React_NativeModulesApple.framework/Headers",
"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers",
"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios",
);
IPHONEOS_DEPLOYMENT_TARGET = 13.4; IPHONEOS_DEPLOYMENT_TARGET = 13.4;
LD = ""; LD = "";
LDPLUSPLUS = ""; LDPLUSPLUS = "";

File diff suppressed because it is too large Load diff

View file

@ -18,10 +18,11 @@ class MattermostHardwareKeyboardPackage : TurboReactPackage() {
override fun getReactModuleInfoProvider() = ReactModuleInfoProvider { override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {
mapOf( mapOf(
MattermostHardwareKeyboardImpl.NAME to ReactModuleInfo( MattermostHardwareKeyboardImpl.NAME to ReactModuleInfo(
MattermostHardwareKeyboardImpl.NAME, name = MattermostHardwareKeyboardImpl.NAME,
MattermostHardwareKeyboardImpl.NAME, className = MattermostHardwareKeyboardImpl.NAME,
_canOverrideExistingModule = false, canOverrideExistingModule = false,
_needsEagerInit = false, needsEagerInit = false,
hasConstants = false,
isCxxModule = false, isCxxModule = false,
isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
) )

View file

@ -20,10 +20,11 @@ class MattermostSharePackage : TurboReactPackage() {
val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap() val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
val isTurboModule: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED val isTurboModule: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
moduleInfos[MattermostShareImpl.NAME] = ReactModuleInfo( moduleInfos[MattermostShareImpl.NAME] = ReactModuleInfo(
MattermostShareImpl.NAME, name = MattermostShareImpl.NAME,
MattermostShareImpl.NAME, className = MattermostShareImpl.NAME,
_canOverrideExistingModule = false, canOverrideExistingModule = false,
_needsEagerInit = false, needsEagerInit = false,
hasConstants = false,
isCxxModule = false, isCxxModule = false,
isTurboModule = isTurboModule isTurboModule = isTurboModule
) )

View file

@ -14,8 +14,8 @@ fun ReadableArray.toJson(): JSONArray {
ReadableType.Boolean -> jsonArray.put(this.getBoolean(i)) ReadableType.Boolean -> jsonArray.put(this.getBoolean(i))
ReadableType.Number -> jsonArray.put(this.getDouble(i)) ReadableType.Number -> jsonArray.put(this.getDouble(i))
ReadableType.String -> jsonArray.put(this.getString(i)) ReadableType.String -> jsonArray.put(this.getString(i))
ReadableType.Map -> jsonArray.put(this.getMap(i).toJson()) ReadableType.Map -> this.getMap(i)?.toJson()?.let { jsonArray.put(it) }
ReadableType.Array -> jsonArray.put(this.getArray(i).toJson()) ReadableType.Array -> this.getArray(i)?.toJson()?.let { jsonArray.put(it) }
} }
} }
return jsonArray return jsonArray

View file

@ -18,10 +18,11 @@ class RNUtilsPackage : TurboReactPackage() {
override fun getReactModuleInfoProvider() = ReactModuleInfoProvider { override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {
mapOf( mapOf(
RNUtilsModuleImpl.NAME to ReactModuleInfo( RNUtilsModuleImpl.NAME to ReactModuleInfo(
RNUtilsModuleImpl.NAME, name = RNUtilsModuleImpl.NAME,
RNUtilsModuleImpl.NAME, className = RNUtilsModuleImpl.NAME,
_canOverrideExistingModule = false, canOverrideExistingModule = false,
_needsEagerInit = false, needsEagerInit = false,
hasConstants = false,
isCxxModule = false, isCxxModule = false,
isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
) )

View file

@ -67,5 +67,5 @@ dependencies {
implementation 'com.facebook.react:react-native' implementation 'com.facebook.react:react-native'
implementation 'androidx.security:security-crypto:1.0.0' implementation 'androidx.security:security-crypto:1.0.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib" implementation "org.jetbrains.kotlin:kotlin-stdlib"
implementation 'com.github.mattermost:mattermost-android-pdfium:v1.0.1' implementation 'com.github.mattermost:mattermost-android-pdfium:v1.1.0'
} }

1510
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -30,7 +30,7 @@
"@mattermost/rnutils": "file:./libraries/@mattermost/rnutils", "@mattermost/rnutils": "file:./libraries/@mattermost/rnutils",
"@mattermost/secure-pdf-viewer": "file:./libraries/@mattermost/secure-pdf-viewer", "@mattermost/secure-pdf-viewer": "file:./libraries/@mattermost/secure-pdf-viewer",
"@msgpack/msgpack": "3.1.1", "@msgpack/msgpack": "3.1.1",
"@nozbe/watermelondb": "0.28.0", "@nozbe/watermelondb": "0.28.1-0",
"@react-native-camera-roll/camera-roll": "7.10.0", "@react-native-camera-roll/camera-roll": "7.10.0",
"@react-native-clipboard/clipboard": "1.16.2", "@react-native-clipboard/clipboard": "1.16.2",
"@react-native-community/cli": "15.1.3", "@react-native-community/cli": "15.1.3",
@ -53,7 +53,7 @@
"deep-equal": "2.2.3", "deep-equal": "2.2.3",
"deepmerge": "4.3.1", "deepmerge": "4.3.1",
"emoji-regex": "10.4.0", "emoji-regex": "10.4.0",
"expo": "52.0.44", "expo": "52.0.47",
"expo-application": "6.0.2", "expo-application": "6.0.2",
"expo-crypto": "14.0.2", "expo-crypto": "14.0.2",
"expo-device": "7.0.3", "expo-device": "7.0.3",
@ -74,7 +74,7 @@
"react": "18.3.1", "react": "18.3.1",
"react-freeze": "1.0.4", "react-freeze": "1.0.4",
"react-intl": "7.1.10", "react-intl": "7.1.10",
"react-native": "0.76.9", "react-native": "0.77.3",
"react-native-background-timer": "2.4.1", "react-native-background-timer": "2.4.1",
"react-native-document-picker": "9.3.1", "react-native-document-picker": "9.3.1",
"react-native-dotenv": "3.4.11", "react-native-dotenv": "3.4.11",
@ -121,10 +121,10 @@
"@babel/preset-typescript": "7.27.0", "@babel/preset-typescript": "7.27.0",
"@babel/register": "7.25.9", "@babel/register": "7.25.9",
"@babel/runtime": "7.27.0", "@babel/runtime": "7.27.0",
"@react-native/babel-preset": "0.76.9", "@react-native/babel-preset": "0.77.3",
"@react-native/eslint-config": "0.76.9", "@react-native/eslint-config": "0.77.3",
"@react-native/metro-config": "0.76.9", "@react-native/metro-config": "0.77.3",
"@react-native/typescript-config": "0.76.9", "@react-native/typescript-config": "0.77.3",
"@stylistic/eslint-plugin-ts": "4.2.0", "@stylistic/eslint-plugin-ts": "4.2.0",
"@testing-library/react-hooks": "8.0.1", "@testing-library/react-hooks": "8.0.1",
"@testing-library/react-native": "13.2.0", "@testing-library/react-native": "13.2.0",
@ -176,6 +176,7 @@
}, },
"scripts": { "scripts": {
"android": "react-native run-android", "android": "react-native run-android",
"apply-16kb-pagesize-patch": "node ./scripts/android-16kb-pagesize/apply-patch.js ./scripts/android-16kb-pagesize/9325-full.diff --apply",
"build:android": "./scripts/build.sh apk", "build:android": "./scripts/build.sh apk",
"build:android-unsigned": "./scripts/build.sh apk unsigned", "build:android-unsigned": "./scripts/build.sh apk unsigned",
"build:ios": "./scripts/build.sh ipa", "build:ios": "./scripts/build.sh ipa",
@ -227,10 +228,10 @@
"react-test-renderer": "^18.3.1" "react-test-renderer": "^18.3.1"
}, },
"@react-native-community/datetimepicker": { "@react-native-community/datetimepicker": {
"react-native": "^0.76.5" "react-native": "^0.77.3"
}, },
"react-native-windows": { "react-native-windows": {
"react-native": "^0.76.5" "react-native": "^0.77.3"
}, },
"@react-native/eslint-config@0.76.5": { "@react-native/eslint-config@0.76.5": {
"@typescript-eslint/eslint-plugin": "^8.29.1" "@typescript-eslint/eslint-plugin": "^8.29.1"

View file

@ -383,18 +383,18 @@ index 551f72b..f275c18 100644
- override fun onInterceptTouchEvent(event: MotionEvent): Boolean { - override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
- mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) - mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher())
+ override fun onInterceptTouchEvent(event: MotionEvent?): Boolean { + override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
+ event?.let { + getEventDispatcher()?.let {
+ mJSTouchDispatcher.handleTouchEvent(it, getEventDispatcher()!!) + mJSTouchDispatcher.handleTouchEvent(event, it)
+ } + }
return super.onInterceptTouchEvent(event) return super.onInterceptTouchEvent(event)
} }
- override fun onTouchEvent(event: MotionEvent): Boolean { - override fun onTouchEvent(event: MotionEvent): Boolean {
- mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher()) - mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher())
+ override fun onTouchEvent(event: MotionEvent?): Boolean { + override fun onTouchEvent(event: MotionEvent): Boolean {
+ event?.let { + getEventDispatcher()?.let {
+ mJSTouchDispatcher.handleTouchEvent(it, getEventDispatcher()!!) + mJSTouchDispatcher.handleTouchEvent(event, it)
+ } + }
super.onTouchEvent(event) super.onTouchEvent(event)
return true return true

View file

@ -0,0 +1,392 @@
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 9dbffd7ca6..bd70fffb9c 100644
--- a/app/components/expo_image/index.tsx
+++ b/app/components/expo_image/index.tsx
@@ -8,6 +8,8 @@ import Animated from 'react-native-reanimated';
import {useServerUrl} from '@context/server';
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;
@@ -25,13 +27,13 @@ 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;
}
// 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,
@@ -43,13 +45,13 @@ const ExpoImage = forwardRef<Image, ExpoImageProps>(({id, ...props}, ref) => {
}, [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`,
@@ -74,13 +76,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,
@@ -92,13 +94,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

View file

@ -0,0 +1,232 @@
#!/usr/bin/env node
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
/**
* Script to apply 16KB page size compatibility patches from a diff file.
* This automates the process of updating dependencies and applying code changes
* for Android 16KB page size support.
*
* Usage:
* node scripts/apply-16kb-pagesize-patch.js <diff-file> [--dry-run|--apply]
*
* Example:
* node scripts/apply-16kb-pagesize-patch.js 9325-full.diff --apply
*/
const {execSync} = require('child_process');
const fs = require('fs');
// ============================================================================
// CONSTANTS
// ============================================================================
const COLORS = {
reset: '\x1b[0m',
bright: '\x1b[1m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
red: '\x1b[31m',
cyan: '\x1b[36m',
};
// Files to apply from the diff (excluding node_modules and package-lock.json)
// git apply will handle everything including file renames
const FILES_TO_EXCLUDE = [
'node_modules/*',
'package-lock.json',
];
// ============================================================================
// UTILITIES
// ============================================================================
function log(message, color = 'reset') {
// eslint-disable-next-line no-console
console.log(`${COLORS[color]}${message}${COLORS.reset}`);
}
function exec(command, options = {}) {
try {
return execSync(command, {
encoding: 'utf8',
stdio: options.silent ? 'pipe' : 'inherit',
...options,
});
} catch (error) {
if (!options.ignoreError) {
throw error;
}
return null;
}
}
// ============================================================================
// MAIN FUNCTIONS
// ============================================================================
function applyDiffChanges(diffPath, dryRun) {
log('\n📝 Applying changes from diff file', 'bright');
if (!fs.existsSync(diffPath)) {
log(`✗ Diff file not found: ${diffPath}`, 'red');
process.exit(1);
}
if (dryRun) {
log(' [DRY RUN] Would apply all changes using git apply', 'yellow');
log(' (excluding node_modules and package-lock.json)', 'yellow');
return;
}
try {
log(' Applying all changes (including file renames)...', 'cyan');
// Build exclude arguments
const excludeArgs = FILES_TO_EXCLUDE.map((pattern) => `--exclude='${pattern}'`).join(' ');
// Apply the diff, excluding node_modules and package-lock.json
exec(`git apply ${excludeArgs} ${diffPath}`, {silent: true});
log(' ✓ All changes applied successfully', 'green');
log(' ✓ Patch files renamed automatically', 'green');
} catch (error) {
log(` ✗ Failed to apply diff: ${error.message}`, 'red');
throw error;
}
}
function installUpdatedPackages(diffPath, dryRun) {
log('\n📦 Installing updated packages', 'bright');
if (dryRun) {
log(' [DRY RUN] Would run: npm install --ignore-scripts', 'yellow');
return;
}
try {
// Read package.json to get the list of changed packages
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const dependencies = {...packageJson.dependencies, ...packageJson.devDependencies};
// Extract package names from diff
const diffContent = fs.readFileSync(diffPath, 'utf8');
const packageChanges = [];
const lines = diffContent.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
// Look for package.json dependency changes
if (line.startsWith('+ "expo') || line.startsWith('- "expo')) {
const match = line.match(/"([^"]+)":\s*"([^"]+)"/);
if (match && line.startsWith('+')) {
const [, pkgName] = match;
if (dependencies[pkgName] && !packageChanges.includes(pkgName)) {
packageChanges.push(pkgName);
}
}
}
}
if (packageChanges.length > 0) {
log(` Installing ${packageChanges.length} updated packages...`, 'cyan');
log(` Packages: ${packageChanges.join(', ')}`, 'cyan');
// Install only the changed packages to update package-lock.json
exec(`npm install ${packageChanges.join(' ')} --ignore-scripts`);
log(' ✓ Packages installed successfully', 'green');
} else {
log(' No package changes detected', 'yellow');
}
} catch (error) {
log(` ✗ Failed to install packages: ${error.message}`, 'red');
throw error;
}
}
function applyPatchFiles(dryRun) {
log('\n🔧 Applying patch files', 'bright');
if (dryRun) {
log(' [DRY RUN] Would run: npx patch-package', 'yellow');
return;
}
try {
exec('npx patch-package');
log(' ✓ Patch files applied successfully', 'green');
} catch (error) {
log(` ✗ Failed to apply patch files: ${error.message}`, 'red');
throw error;
}
}
function showSummary(dryRun) {
log('\n' + '='.repeat(70), 'cyan');
if (dryRun) {
log('DRY RUN COMPLETE', 'bright');
log('Run with --apply to actually apply the changes', 'yellow');
} else {
log('✓ ALL CHANGES APPLIED SUCCESSFULLY', 'green');
log('\n⚠ IMPORTANT:', 'yellow');
log('These changes are for Android builds ONLY', 'yellow');
log('DO NOT commit these changes to the repository', 'yellow');
log('\nNext steps:', 'bright');
log('1. Build your Android app', 'cyan');
log('2. After building, revert these changes with: git checkout .', 'cyan');
}
log('='.repeat(70), 'cyan');
}
// ============================================================================
// MAIN
// ============================================================================
function main() {
const args = process.argv.slice(2);
if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
log('Usage: node scripts/apply-16kb-pagesize-patch.js <diff-file> [--dry-run|--apply]', 'bright');
log('\nOptions:', 'bright');
log(' --dry-run Preview changes without applying them (default)', 'cyan');
log(' --apply Actually apply the changes', 'cyan');
log(' --help, -h Show this help message', 'cyan');
log('\nExample:', 'bright');
log(' node scripts/apply-16kb-pagesize-patch.js 9325-full.diff --apply', 'cyan');
process.exit(0);
}
const diffPath = args[0];
const dryRun = !args.includes('--apply');
log('\n' + '='.repeat(70), 'cyan');
log('16KB PAGE SIZE PATCH APPLICATION', 'bright');
log('='.repeat(70), 'cyan');
log(`Diff file: ${diffPath}`, 'cyan');
log(`Mode: ${dryRun ? 'DRY RUN' : 'APPLY'}`, dryRun ? 'yellow' : 'green');
log('='.repeat(70), 'cyan');
try {
// Step 1: Apply diff changes using git apply (handles renames automatically)
applyDiffChanges(diffPath, dryRun);
// Step 2: Install updated packages
installUpdatedPackages(diffPath, dryRun);
// Step 3: Apply patch files
applyPatchFiles(dryRun);
// Show summary
showSummary(dryRun);
} catch (error) {
log('\n✗ Script failed with error:', 'red');
log(error.message, 'red');
process.exit(1);
}
}
main();

View file

@ -4,17 +4,32 @@ function execute() {
cd fastlane && NODE_ENV=production bundle exec fastlane $1 $2 cd fastlane && NODE_ENV=production bundle exec fastlane $1 $2
} }
function cleanupAndroid16kbPagesizePatch() {
# Only cleanup if we ran setup (SKIP_SETUP not set)
if [[ -z "$SKIP_SETUP" ]]; then
echo "Reverting 16KB page size patch changes..."
# Get the git root directory to ensure we're in the right place
local git_root=$(git rev-parse --show-toplevel)
cd "$git_root" || return
git checkout -- package.json package-lock.json app.json app/components/expo_image/index.tsx android/buildscript-gradle.lockfile patches/
git clean -fd patches/
echo "✓ Patch changes reverted"
fi
}
function apk() { function apk() {
case $1 in case $1 in
unsigned) unsigned)
echo "Building Android unsigned app" echo "Building Android unsigned app"
setup android setup android
execute android unsigned execute android unsigned
cleanupAndroid16kbPagesizePatch
;; ;;
*) *)
echo "Building Android app" echo "Building Android app"
setup android setup android
execute android build execute android build
cleanupAndroid16kbPagesizePatch
esac esac
} }
@ -55,7 +70,16 @@ function setup() {
if [[ -z "$SKIP_SETUP" ]]; then if [[ -z "$SKIP_SETUP" ]]; then
npm run clean || exit 1 npm run clean || exit 1
npm install --ignore-scripts || exit 1 npm install --ignore-scripts || exit 1
# Apply 16KB page size patch for Android builds (includes npx patch-package)
if [[ "$1" == "android"* ]]; then
echo "Applying 16KB page size compatibility patch for Android"
npm run apply-16kb-pagesize-patch || exit 1
else
# For non-Android builds, just apply regular patches
npx patch-package || exit 1 npx patch-package || exit 1
fi
node node_modules/\@sentry/cli/scripts/install.js || exit 1 node node_modules/\@sentry/cli/scripts/install.js || exit 1
if [[ "$1" == "ios"* ]]; then if [[ "$1" == "ios"* ]]; then