Merge branch 'develop' into valere/call/fix_join_button_on_several_items

This commit is contained in:
Valere 2026-04-17 10:10:04 +02:00
commit 180ad5a281
12 changed files with 120 additions and 15 deletions

View file

@ -16,7 +16,7 @@ jobs:
contents: write
steps:
- name: ⏬ Checkout with LFS
uses: nschloe/action-cached-lfs-checkout@1c185ad576953eab13e35ffe1bffef437d97e9d2 # v1.2.4
uses: nschloe/action-cached-lfs-checkout@385a8ecc719e50b8c71af6ab01a624b486b7c3bc # v1.2.5
- name: Use JDK 21
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:

View file

@ -34,7 +34,7 @@ jobs:
swap-storage: false
- name: ⏬ Checkout with LFS
uses: nschloe/action-cached-lfs-checkout@1c185ad576953eab13e35ffe1bffef437d97e9d2 # v1.2.4
uses: nschloe/action-cached-lfs-checkout@385a8ecc719e50b8c71af6ab01a624b486b7c3bc # v1.2.5
- name: Use JDK 21
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0

View file

@ -43,13 +43,13 @@ jobs:
labels: Record-Screenshots
- name: ⏬ Checkout with LFS (PR)
if: github.event.label.name == 'Record-Screenshots'
uses: nschloe/action-cached-lfs-checkout@1c185ad576953eab13e35ffe1bffef437d97e9d2 # v1.2.4
uses: nschloe/action-cached-lfs-checkout@385a8ecc719e50b8c71af6ab01a624b486b7c3bc # v1.2.5
with:
persist-credentials: false
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.ref }}
- name: ⏬ Checkout with LFS (Branch)
if: github.event_name == 'workflow_dispatch'
uses: nschloe/action-cached-lfs-checkout@1c185ad576953eab13e35ffe1bffef437d97e9d2 # v1.2.4
uses: nschloe/action-cached-lfs-checkout@385a8ecc719e50b8c71af6ab01a624b486b7c3bc # v1.2.5
with:
persist-credentials: false
- name: ☕️ Use JDK 21

View file

@ -49,7 +49,7 @@ jobs:
sudo swapon /mnt/swapfile
sudo swapon --show
- name: ⏬ Checkout with LFS
uses: nschloe/action-cached-lfs-checkout@1c185ad576953eab13e35ffe1bffef437d97e9d2 # v1.2.4
uses: nschloe/action-cached-lfs-checkout@385a8ecc719e50b8c71af6ab01a624b486b7c3bc # v1.2.5
with:
# Ensure we are building the branch and not the branch after being merged on develop
# https://github.com/actions/checkout/issues/881

View file

@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
name: Validate
steps:
- uses: nschloe/action-cached-lfs-checkout@1c185ad576953eab13e35ffe1bffef437d97e9d2 # v1.2.4
- uses: nschloe/action-cached-lfs-checkout@385a8ecc719e50b8c71af6ab01a624b486b7c3bc # v1.2.5
- run: |
./tools/git/validate_lfs.sh

View file

@ -1,3 +1,62 @@
Changes in Element X v26.04.3
=============================
<!-- Release notes generated using configuration in .github/release.yml at v26.04.3 -->
## What's Changed
### ✨ Features
* Sign in with element classic final by @bmarty in https://github.com/element-hq/element-x-android/pull/6296
* Take into account homeserver capabilities by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6507
### 🙌 Improvements
* feat: Default to camera muted when joining ongoing voice call by @BillCarsonFr in https://github.com/element-hq/element-x-android/pull/6574
### 🐛 Bugfixes
* Fix crash in FetchPushForegroundService: No super method onTimeout by @bmarty in https://github.com/element-hq/element-x-android/pull/6547
* Ensure mark as fully read is called only once when leaving the timeline by @bmarty in https://github.com/element-hq/element-x-android/pull/6550
* Fix `isInAirGappedEnvironment` check for older APIs by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6573
* Fix loading initial items of non-live timelines by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6598
### 🗣 Translations
* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/6537
* Sync Strings - new translations in Japanese and Vietnamese by @ElementBot in https://github.com/element-hq/element-x-android/pull/6568
### 🧱 Build
* Fix module dependencies by @bmarty in https://github.com/element-hq/element-x-android/pull/6559
### 🚧 In development 🚧
* Add confirmation dialog when inviting users with unknown identities by @kaylendog in https://github.com/element-hq/element-x-android/pull/6523
* Feature: add room threads list by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6575
### Dependency upgrades
* fix(deps): update media3 to v1.10.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6529
* fix(deps): update dependency io.github.sergio-sastre.composablepreviewscanner:android to v0.8.2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6525
* fix(deps): update metro to v0.12.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6543
* fix(deps): update kotlinpoet to v2.3.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6528
* Sync compound tokens https://github.com/element-hq/compound-design-tokens/releases/tag/v10.0.0 by @bmarty in https://github.com/element-hq/element-x-android/pull/6517
* fix(deps): update dependency io.sentry:sentry-android to v8.37.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6508
* fix(deps): update dependency org.maplibre.gl:android-sdk to v13.0.2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6546
* Update codecov/codecov-action action to v6 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6521
* Update telephoto to v0.19.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6558
* Update dependency net.zetetic:sqlcipher-android to v4.14.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6552
* Update dependency org.matrix.rustcomponents:sdk-android to v26.04.8 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6553
* Update gradle/actions action to v6.1.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6562
* Update metro to v0.13.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6565
* Update dependency org.matrix.rustcomponents:sdk-android to v26.04.13 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6570
* Update wysiwyg to v2.41.3 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6572
* Update dependency com.google.testparameterinjector:test-parameter-injector to v1.22 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6576
* Use `Coil3` for `ZoomableAsyncImage` by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6582
* Update dependency org.matrix.rustcomponents:sdk-android to v26.04.15 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6595
* Update nschloe/action-cached-lfs-checkout action to v1.2.5 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6600
### Others
* Fix portrait image metadata when uploading without media optimization by @kalix127 in https://github.com/element-hq/element-x-android/pull/6362
* Fix Threads not tappable in pinned messages list by @bxdxnn in https://github.com/element-hq/element-x-android/pull/6535
* Reduce log level of activity lifecycle from warning to debug. by @bmarty in https://github.com/element-hq/element-x-android/pull/6548
* Remove spaces features flags by @bmarty in https://github.com/element-hq/element-x-android/pull/6560
* Remove space announcement by @bmarty in https://github.com/element-hq/element-x-android/pull/6561
* Update metro to v0.13.2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6571
* Take into account the value of FeatureFlags.SignInWithClassic by @bmarty in https://github.com/element-hq/element-x-android/pull/6586
* Add extra logs for timeline pagination by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6589
* Scrollable media caption - tweaks by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6583
* Split developer settings into 2 screens to be able to access global settings when no logged in. by @bmarty in https://github.com/element-hq/element-x-android/pull/6587
**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v26.04.2...v26.04.3
Changes in Element X v26.04.2
=============================

View file

@ -0,0 +1,2 @@
Main changes in this version: bug fixes and improvements.
Full changelog: https://github.com/element-hq/element-x-android/releases

View file

@ -84,6 +84,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.transform
import kotlinx.coroutines.launch
import timber.log.Timber
@ -260,11 +261,16 @@ private fun TimelinePrefetchingHelper(
firstVisibleItemIndex + layoutInfo.visibleItemsInfo.size >= layoutInfo.totalItemsCount - 40
}
// If we have no timeline items, we need to back paginate to load some messages. This usually happens on all timelines except for live ones.
// This automatic pagination was previously done by the SDK, and we received a `Reset` update, but now we need to do it ourselves.
val isEmptyTimelineFlow = layoutInfoFlow.map { it.totalItemsCount == 0 }
combine(
isCloseToStartOfLoadedTimelineFlow.distinctUntilChanged(),
isScrollingFlow.distinctUntilChanged(),
) { needsPrefetch, isScrolling ->
needsPrefetch && isScrolling
isEmptyTimelineFlow,
) { needsPrefetch, isScrolling, isEmptyAndNeedsBackPagination ->
isEmptyAndNeedsBackPagination || needsPrefetch && isScrolling
}
.distinctUntilChanged()
.collectLatest { needsPrefetch ->

View file

@ -522,6 +522,9 @@ class MessagesViewTest {
rule.setMessagesView(
state = stateWithActionListState,
)
// Clear initial 'LoadMore' event emitted when setting the state
eventsRecorder.clear()
val verifiedUserSendFailure = rule.activity.getString(CommonStrings.screen_timeline_item_menu_send_failure_changed_identity, "Alice")
rule.onNodeWithText(verifiedUserSendFailure).performClick()
// Give time for the close animation to complete
@ -585,6 +588,9 @@ class MessagesViewTest {
),
)
rule.setMessagesView(state = state)
// Clear initial 'LoadMore' event emitted when setting the state
eventsRecorder.clear()
rule.onNodeWithText("This is a pinned message").performClick()
eventsRecorder.assertSingle(TimelineEvent.FocusOnEvent(AN_EVENT_ID, debounce = FOCUS_ON_PINNED_EVENT_DEBOUNCE_DURATION_IN_MILLIS.milliseconds))
}
@ -601,6 +607,9 @@ class MessagesViewTest {
timelineState = aTimelineState(eventSink = eventsRecorder)
)
rule.setMessagesView(state = state)
// Clear initial 'LoadMore' event emitted when setting the state
eventsRecorder.clear()
val text = rule.activity.getString(R.string.screen_room_timeline_tombstoned_room_action)
// The bottomsheet subcompose seems to make the node to appear twice
rule.onAllNodesWithText(text).onFirst().performClick()

View file

@ -67,24 +67,31 @@ class TimelineViewTest {
@Test
fun `reaching the end of the timeline does not send a LoadMore event`() {
val eventsRecorder = EventsRecorder<TimelineEvent>(expectEvents = false)
val eventsRecorder = EventsRecorder<TimelineEvent>()
rule.setTimelineView(
state = aTimelineState(
timelineItems = persistentListOf(aTimelineItemEvent(content = aTimelineItemImageContent())),
eventSink = eventsRecorder,
),
)
eventsRecorder.assertSingle(TimelineEvent.OnScrollFinished(firstIndex = 0))
}
@Test
fun `scroll to bottom on live timeline does not emit the Event`() {
val eventsRecorder = EventsRecorder<TimelineEvent>(expectEvents = false)
val eventsRecorder = EventsRecorder<TimelineEvent>()
rule.setTimelineView(
state = aTimelineState(
timelineItems = persistentListOf(aTimelineItemEvent(content = aTimelineItemImageContent())),
isLive = true,
eventSink = eventsRecorder,
),
forceJumpToBottomVisibility = true,
)
eventsRecorder.assertSingle(TimelineEvent.OnScrollFinished(firstIndex = 0))
eventsRecorder.clear()
val contentDescription = rule.activity.getString(CommonStrings.a11y_jump_to_bottom)
rule.onNodeWithContentDescription(contentDescription).performClick()
}
@ -94,15 +101,33 @@ class TimelineViewTest {
val eventsRecorder = EventsRecorder<TimelineEvent>()
rule.setTimelineView(
state = aTimelineState(
timelineItems = persistentListOf(aTimelineItemEvent(content = aTimelineItemImageContent())),
isLive = false,
eventSink = eventsRecorder,
),
)
eventsRecorder.assertSingle(TimelineEvent.OnScrollFinished(firstIndex = 0))
eventsRecorder.clear()
val contentDescription = rule.activity.getString(CommonStrings.a11y_jump_to_bottom)
rule.onNodeWithContentDescription(contentDescription).performClick()
eventsRecorder.assertSingle(TimelineEvent.JumpToLive)
}
@Test
fun `an empty timeline triggers a prefetch`() {
val eventsRecorder = EventsRecorder<TimelineEvent>()
rule.setTimelineView(
state = aTimelineState(
timelineItems = persistentListOf(),
eventSink = eventsRecorder,
),
)
eventsRecorder.assertSingle(TimelineEvent.LoadMore(Timeline.PaginationDirection.BACKWARDS))
}
@Test
fun `show shield dialog`() {
val eventsRecorder = EventsRecorder<TimelineEvent>()
@ -133,11 +158,15 @@ class TimelineViewTest {
val eventsRecorder = EventsRecorder<TimelineEvent>()
rule.setTimelineView(
state = aTimelineState(
timelineItems = persistentListOf(aTimelineItemEvent(content = aTimelineItemImageContent())),
isLive = false,
eventSink = eventsRecorder,
messageShield = aCriticalShield(),
),
)
eventsRecorder.assertSingle(TimelineEvent.OnScrollFinished(firstIndex = 0))
eventsRecorder.clear()
rule.clickOn(CommonStrings.action_ok)
eventsRecorder.assertSingle(TimelineEvent.HideShieldDialog)
}

View file

@ -36,7 +36,7 @@ roborazzi = "1.59.0"
# Jetbrain
datetime = "0.7.1"
serialization_json = "1.10.0"
serialization_json = "1.11.0"
#other
coil = "3.4.0"
@ -80,7 +80,7 @@ kotlinpoet-ksp = { module = "com.squareup:kotlinpoet-ksp", version.ref = "kotlin
kover_gradle_plugin = { module = "org.jetbrains.kotlinx:kover-gradle-plugin", version.ref = "kover" }
ksp_gradle_plugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
# https://firebase.google.com/docs/android/setup#available-libraries
google_firebase_bom = "com.google.firebase:firebase-bom:34.11.0"
google_firebase_bom = "com.google.firebase:firebase-bom:34.12.0"
firebase_appdistribution_gradle = { module = "com.google.firebase:firebase-appdistribution-gradle", version.ref = "firebaseAppDistribution" }
autonomousapps_dependencyanalysis_plugin = { module = "com.autonomousapps:dependency-analysis-gradle-plugin", version.ref = "dependencyAnalysis" }
ksp_plugin = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" }
@ -89,7 +89,7 @@ google_tink = "com.google.crypto.tink:tink-android:1.21.0"
# AndroidX
androidx_core = { module = "androidx.core:core", version.ref = "core" }
androidx_corektx = { module = "androidx.core:core-ktx", version.ref = "core" }
androidx_annotationjvm = "androidx.annotation:annotation-jvm:1.9.1"
androidx_annotationjvm = "androidx.annotation:annotation-jvm:1.10.0"
androidx_datastore_preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastore" }
androidx_datastore_datastore = { module = "androidx.datastore:datastore", version.ref = "datastore" }
androidx_exifinterface = "androidx.exifinterface:exifinterface:1.4.2"
@ -233,7 +233,7 @@ sigpwned_emoji4j = "com.sigpwned:emoji4j-core:16.0.0"
metro_runtime = { module = "dev.zacsweers.metro:runtime", version.ref = "metro" }
# Element Call
element_call_embedded = "io.element.android:element-call-embedded:0.19.0"
element_call_embedded = "io.element.android:element-call-embedded:0.19.1"
# Auto services
google_autoservice = { module = "com.google.auto.service:auto-service", version.ref = "autoservice" }

View file

@ -45,7 +45,7 @@ private const val versionMonth = 4
* Release number in the month. Value must be in [0,99].
* Do not update this value. it is updated by the release script.
*/
private const val versionReleaseNumber = 2
private const val versionReleaseNumber = 3
object Versions {
/**