* Fix some isolation errors when compiling with Swift 6.4.
* Update the Design Tokens dependency to include Sendable conformances.
(cherry picked from commit 4608a63e29)
Expose OpenID tokens and homeserver credentials from the client proxy, and
add fork-only services for the HealthChat member directory backend
(api.healthchat.ch) plus a service that reads MSC4133 extended profile
fields directly from the homeserver. Groundwork for the members tab and
the profile screens.
Claude-Session: https://claude.ai/code/session_013qdTbAWsZj2quQzEkagXaS
* Add a Mentions room list filter
Adds a new filter chip to the room list that shows only rooms with
unread mentions, using the new mentions room list filter from the
Rust SDK (matrix-org/matrix-rust-sdk branch matthew/mentions-filter).
The SDK version needs bumping to a release that includes the new
filter kind before this can build against the released components.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Order the room list filters by expected usage
Move Favourites ahead of People and Rooms so the more commonly used
filters (Unreads, Mentions, Favourites) sit first in the chip row —
Rooms and Invites are used rarely enough that it's fine for them to
wrap off the side.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uk8aPxHn3BHCe52L226jdG
* update the SDK and use the appropriate rust filter types
* preview tests + app settings flag for mentions
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Mauro Romito <mauro.romito@element.io>
* Adjust login flow to exclusively use the ServerSelectionScreen
* Move async code to server selection vm
* ServerSelection supports pro picker options
* Use homeserver address for both confirmation and picker modes
* rename ServerSelectionScreenMode
* remove ServerConfirmationScreen
It's been superseded by the ServerSelectionScreen
* rename userInput
* Update strings with latest design strings
* Add server input autocompletion
* Store previous servers in AppSettings and autofill on server signin
* Audit changes for logging
* Enforce lowercase server history storage
* Update tests
* Update Xcode project
* PR review fixups
* Add HomeserverHistoryManager
* Review fixups 2
* Review fixups 3
* Report user presence on app lifecycle transitions
Adds a PresenceReporter driven by the app lifecycle handlers and the sharePresence setting: online when foreground-active and sharing, unavailable when backgrounded and sharing, offline when not sharing. Sends are immediate, deduped, and serialized latest-wins. Background app refresh and the NSE seed the process presence to offline so their sync requests carry no presence side effect. Presence rides on the SDK's process-global state, so every sync path is covered without touching sync lifecycle.
Signed-off-by: Jared L <48422312+lhjt@users.noreply.github.com>
* Add presence reporter tests
Pins the presence reporter invariants: the never-online sweep with sharing off, an immediate online send on foreground-active, dedupe of repeated states, latest-wins ordering of serialized sends, and the NSE offline seed.
Signed-off-by: Jared L <48422312+lhjt@users.noreply.github.com>
* wip: address review comments
Signed-off-by: Jared L <48422312+lhjt@users.noreply.github.com>
* refactor: remove obsolete presence heartbeat
Remove the shared activity snapshot, heartbeat refresh, and notification-extension freshness policy while retaining the session-scoped presence service and its serialized lifecycle reporting. Restore the NSE's intermediate one-time offline seed so the cleanup remains buildable ahead of the final sync-presence correction.
Signed-off-by: Jared L <48422312+lhjt@users.noreply.github.com>
* fix: make notification extension presence-neutral
Configure the built NSE client with offline sync presence without sending an immediate presence update. Keep notification setup non-fatal when presence configuration fails and remove the temporary production test seam.
Signed-off-by: Jared L <48422312+lhjt@users.noreply.github.com>
* chore: restore application lifecycle logging
Restore the pre-existing foreground lifecycle diagnostics that were removed during the presence refactor. Keep presence reporting session-scoped and clarify that background refresh configures the client's sync presence without an immediate update.
Signed-off-by: Jared L <48422312+lhjt@users.noreply.github.com>
---------
Signed-off-by: Jared L <48422312+lhjt@users.noreply.github.com>
* Update the SDK and hook up the status from Room Heroes.
Also start requesting profiles via sss when the feature flag is enabled.
* Add support for subscribing to your own profile.
* Update the SDK and handle API breaks.
* Rename sdkUserThing to rustUserThing for consistency.
* Add user status ClientProxy methods.
* Rename UserStatus.UserSet to UserStatus.Raw.
Wrap the SDK's SearchService in a SearchServiceProxy that publishes typed
message results and paginates on demand, expose it on the ClientProxy, and
enable the search index store on the session. Also opens up the timeline item
factory's message content builder so the proxy can reuse it.
* implemented the content scanner service with caching and a way to use in the state store context
* fix swiftformat comment enforcing
* pr suggestions
homeserverReachabilityPublisher now reports unreachable while suspended so media loading parks instead of failing against a closed store. The reachability banner was keyed off the same publisher, so pausing the client would surface a spurious "Server unreachable" message.
Expose a separate homeserverConnectivityPublisher derived from the sync service state alone (it stays reachable while suspended) and key the banner off that, keeping the suspend-aware publisher for gating work that needs an open store.
`homeserverReachabilityPublisher` was driven directly by the sync service state so stopping sync on pause still reported .reachable. MediaProvider.loadImageRetryingOnReconnection would then retry against a closed store, fail, and bail out permanently because it treated the reachable state as a non-recoverable error.
Make reachability a function of both the desired service state and the latest sync state, computed in one place: store the sync state in the listener and recompute reachability from it, reporting unreachable whenever the client isn't meant to be running. Recompute on suspend and on resume.
* Enable Swift 6.2 with default main actor isolation for the app target
Turn on SWIFT_VERSION 6.2, SWIFT_APPROACHABLE_CONCURRENCY and SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor for the ElementX target, matching the NSE and Share Extension (which already use 6.2 without the main actor default).
# Conflicts:
# ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
* Update the code generation templates for Swift 6
Emit nonisolated/@unchecked Sendable mocks and nonisolated string enums, and mark async mock methods @concurrent so they keep suspending like the real implementations (otherwise intermediate states are unobservable in tests). Includes the regenerated mocks and strings.
# Conflicts:
# ElementX/Sources/Mocks/Generated/GeneratedMocks.swift
* Make the data layer and services nonisolated and Sendable
Annotate the value-type models, Rust SDK proxy wrappers, timeline item graph, settings, logging and NSE-shared types as nonisolated, and conform the service protocols to Sendable so their existentials can cross isolation boundaries. These types run off the main actor and no longer inherit the target's default main actor isolation.
* Adopt the new isolation across call sites, mocks and signatures
Update call sites, closure signatures and mock configuration helpers to match the nonisolated/Sendable data layer, including the main actor isolated mock inits and the @Sendable filter on recentlyVisitedRooms.
^ Conflicts:
^ ElementX/Sources/Services/SecureBackup/SecureBackupController.swift
* Remove redundant @MainActor annotations
With the app target defaulting to main actor isolation, the explicit @MainActor on view models, coordinators, views and their protocols is no longer required.
* Fix concurrency hotspots surfaced by the migration
Resolve the room summary main-thread deadlock by moving diff processing onto AsyncStreams, add the SDKListener.onMainActor FIFO bridge for SDK callbacks, hop KVO/timer/UIKit callbacks to the main actor via assumeIsolated, add isolated deinits, and apply the few justified nonisolated(unsafe) escapes for queue-confined Apple APIs.
* Fix the unit tests for Swift 6 concurrency
Hop the waitForConfirmation body onto the caller's actor (Swift Testing runs confirmation closures off-actor), and adjust the affected suites and async signatures.
* offload diffs on concurrent threads instead of main actor
* make room info protocols sendable
* use a task group for fetching data so that everything runs concurrently in the TextRoomTimelineView when getting the preview.
* use the generic onMainActor implementation, which already makes a stream and send the continuation on the main actor.
* small pr comments issues being addressed
* update enterprise
* Update StaticCode to 1.1.0 and specify the required Swift isolation.
* fix ElementCallServiceTests
* update enterprise
* re-generate mocks
* update enterprise
* enterprise new code conformed to swift 6
---------
Co-authored-by: Doug <douglase@element.io>
The send queue auto-enable listener fires whenever the queue is believed
off and the homeserver is reachable. While the client is suspended this
could re-enable the queue and potentially fall straight back into a re-enable
loop.
Gate the listener on the desired service state so queues are only restarted
when we intend to be running, and nudge the listener on resume so the queue
recovers reliably. The SDK only re-enables queues when client.resume() runs,
which is gated behind clientPausingAndResumingEnabled, so the nudge keeps
recovery uniform across builds rather than depending on the flag.
`pauseServices` took a completion block only because it was historically
called from `deinit`, which can't await (the SE-0371 note). `deinit` now
stops the sync itself, so the sole remaining caller is the AppCoordinator,
which can await instead.
Make `pauseServices` async and update the AppCoordinator background-task
and lifecycle call sites to await it, calling the OS-facing completions
(endBackgroundTask / setTaskCompleted) afterwards. This also removes the
`MainActor.assumeIsolated` workaround — awaiting a @MainActor method hops
onto the main actor cleanly — and fixes a latent bug where a nil `self` in
the background app refresh expiration handler would skip setTaskCompleted.
Pause and resume previously ran as independent, unsynchronised tasks:
`pauseServices` stopped the sync and paused the client from a detached
`Task`, while `resumeServices` resumed and started the sync directly.
With no ordering between them, a late background pause could land after a
foreground resume — leaving the client suspended and the sync stopped
while the app was active, which broke everything until the next relaunch.
Route both through a single serialised reconciler: each request records
the desired state and chains onto the previous transition, and the
reconcile always drives the SDK to the *latest* desired state. Transitions
can no longer interleave and the most recent intent always wins.
On deinit we no longer pause the client — it's being deallocated, so the
SDK tears it down anyway; we just stop the sync and cancel the delegate.
* Create AnalyticsServiceProtocol and conform AnalyticsService
* Replace AnalyticsService properties and arguments with AnalyticsServiceProtocol
* Inline AnalyticsServiceMock replacing old mock
* handle more complex AnalyticsServiceMock callsites
* move documentation from AnalyticsService to AnalyticsServiceProtocol
* handle the details to invite users flow.
* implemented the room creation in the invite screen, and its dismissal + navigaton to the newly created room
* updated preview and unit tests
* pr suggestions
This will use an underlying SDK method and send a private read receipt plus a fully read marker in every single room the user is part of. It will most likely be a long operation that will get rate limited so the task is set to run detached for as long as it takes.
* Track active live location sessions by ID instead of timeout.
# Conflicts:
# ElementX/Sources/Services/Location/LiveLocationManager.swift
* implemented a system to promote starting session to active sesessions to send locations at the right time, and a system to remove a local session if it's handled by an external device.
* pr suggestions
---------
Co-authored-by: Doug <douglase@element.io>
Add support for homeserver capabilities to disable editing your user profile.
Also updates editable avatar size/formatting to match the latest Figma at the same time.