Commit Graph

500 Commits

Author SHA1 Message Date
Jared L cff46137b9 Report user presence on app lifecycle transitions (#5838)
* 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>
2026-07-22 15:23:36 +01:00
Stefan Ceriu 4eb0863f3a Surface search set query errors with an error indicator 2026-07-22 15:40:56 +03:00
Doug 32a54c5b71 Hook up the emoji picker to the custom status row. (#5902)
* Refactor EmojiPickerScreen to take a continuation instead of a timeline/itemID.

* Hook up the emoji picker to the custom status row.
2026-07-22 13:35:37 +01:00
Mauro b5b28b9986 Support sending gallery messages behind a feature flag (#5909)
dds sending of multi-media "gallery" messages, gated behind the new galleryEnabled developer option (Developer Options → Room, off by default). Rendering of received galleries ships in a separate PR.

Wires sendGallery through TimelineProxy/TimelineController onto the SDK's Timeline.sendGallery.
MediaUploadPreviewScreen sends selected items as one gallery when the flag is on.
Co-authored with the original author of #5601.

NOTE: This PR allows to send gallery messages, but they won't be rendered without the gallery timeline item PR.
2026-07-21 17:25:30 +02:00
Mauro Romito 5d1e15f308 Revert "Support sending gallery messages behind a feature flag"
This reverts commit 6a2ed331fa.
2026-07-21 12:44:03 +02:00
Mauro Romito 6a2ed331fa Support sending gallery messages behind a feature flag
Adds the ability to send a gallery message (multiple attachments in one message)
via the media upload preview, wired through the timeline controller/proxy to the
SDK's sendGallery. Gated by a `galleryEnabled` developer flag (default off),
matching Element X Android — with the flag off, attachments are sent as
individual messages as before.

Extends the community PR #5601, rebased onto develop. Tracking:
element-hq/element-meta#3201

Co-authored-by: svetoslav.mitov <svetoslav.mitov@sportinno.com>
2026-07-21 12:09:07 +02:00
Mauro Romito 762e5ad0ff Revert "Support sending gallery messages behind a feature flag"
This reverts commit 9a61d870d6.
2026-07-21 12:00:03 +02:00
Mauro Romito 9a61d870d6 Support sending gallery messages behind a feature flag
Adds the ability to send a gallery message (multiple attachments in one message)
via the media upload preview, wired through the timeline controller/proxy to the
SDK's sendGallery. Gated by a `galleryEnabled` developer flag (default off),
matching Element X Android — with the flag off, attachments are sent as
individual messages as before.

Extends the community PR #5601, rebased onto develop. Tracking:
element-hq/element-meta#3201

Co-authored-by: svetoslav.mitov <svetoslav.mitov@sportinno.com>
2026-07-21 11:34:44 +02:00
Mauro 9093631f8b Periphery cleanup (#5893) 2026-07-20 11:16:11 +02:00
Doug a0ec5ed9dd Add the UI for your own user status in the Settings screen. (#5888)
* Show the user's own Status emoji on the SettingsScreen.

* Add the UI for setting your own status.

* Add placeholder action for selecting a custom emoji and fix some accessibility issues.
2026-07-17 12:21:51 +01:00
Matthew Hodgson 834938f585 don't keep re-prompting the user to migrate if they get spontaneously logged out. (#5844) 2026-07-07 15:28:40 +02:00
Stefan Ceriu 02d9ed1f0e Address search PR review comments
- Drop the redundant searchService coordinator/view model parameter; derive it from the client proxy.
- Rename the globalSearch avatar size to search.
- Lift the query observation streams out of their tasks.
- Restore the appeared and updateVisibleRange comments.
- Use CompoundIcon defaults and a scaledFrame for media previews.
- Simplify the result mapping with compactMap(makeResult) and drop unsupported events by returning nil.
- Move the preview helpers beneath the previews.
2026-07-03 13:39:45 +03:00
Stefan Ceriu 4fbfc87551 Add a Messages tab to global search
Split global search into Rooms and Messages tabs. The Messages tab lists
matching events with the room's name and avatar, a sender-prefixed preview,
rich media (image/video/audio/file) previews, and a loading indicator, then
paginates as you scroll. Queries are debounced and the previous one is
superseded so late results can't clobber a newer search.
2026-07-03 13:39:45 +03:00
Doug 3ef66cdd05 Rename UserProfileProxy to UserProfile. It's a pure struct and proxies nothing.
Also remove the redundant `userID` property given `id` already exists (for Identifiable conformance).
2026-07-02 13:09:34 +01:00
Doug 123661537a Make LinkNewDeviceScreen fall back to the App Lock PIN code when there's no passcode. (#5794)
* Fall back to the AppLock PIN code when there's no passcode.

* Add extra tests on the LinkNewDeviceFlowCoordinator.

* Misc tweaks for clarification.

* Regenerate snapshots.
2026-07-01 10:13:18 +01:00
Doug f3da459d16 Ensure that the current user is the device owner before linking a new device. (#5773) 2026-06-26 16:24:18 +01:00
Stefan Ceriu 0bd32d24fd Switch to a custom HomeserverReachability instead of different publishers 2026-06-24 20:49:49 +03:00
Stefan Ceriu 3ccaa04554 Don't show the server unreachable banner while the client is suspended
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.
2026-06-24 20:49:49 +03:00
Stefan Ceriu c5653c2208 Allow returning from global search with the escape key
cmd+k jumps to the search tab but left users with no way back. Pressing
escape in the search field now returns to the tab they came from (never
into search itself).

Escape is handled at the search field's pressesBegan, alongside the
existing arrow-key navigation, since the focused UIKit field swallows
SwiftUI keyboard shortcuts.
2026-06-22 16:54:30 +03:00
Mauro Romito 3aedd0ccff swiftformat now enforces newlines for ifs 2026-06-19 15:28:27 +02:00
Stefan Ceriu 7f1b6086ae Search tab (#5754)
* Add a developer flag for the search tab
Introduces a globalSearchEnabled user preference (off by default) with a toggle in Developer Options, used to gate the new search experience.

* Support search role tabs in the tab coordinator
Migrates the NavigationTabCoordinator to SwiftUI's value-based Tab API and adds an isSearch option so a tab can adopt the iOS 26 .search role, which detaches it into the trailing search button in the tab bar.

* Moves room search to a new screen
Adds a new screen that filters the alternate room summary provider as you type, shows an empty state, and lists matching rooms with their matrix identifier. Supports hardware keyboard selection (arrow keys to move through results, return to open) by reaching into the system search field.

* Present search in a dedicated tab
Adds the search tab to the chats flow on iOS 26 when the flag is enabled, rendered as the detached .search role button. The Cmd+K shortcut now selects this tab, and the home screen's inline search is hidden while the tab is available.

* Remove the old global search screen
The dedicated search tab replaces the Cmd+K floating window, so the GlobalSearchScreen, its window plumbing in the WindowManager, and its presentation in the chats flow are all removed.
2026-06-19 13:50:17 +03:00
Mauro a520d94760 Swift 6 Migration (#5733)
* 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>
2026-06-18 17:55:31 +02:00
Michael 7edca8b5a1 Add a recovery key screen hook. (#5684)
update generateRecoveryKey to take a passphrase option

Wire up AppHooks with recovery key hook

Update xcodeproj

Review fixups

Review fixups

Make the `SecureBackupRecoveryState.viewMode` extension private

Bump the enterprise submodule
2026-06-18 13:28:57 +01:00
Mauro da5360c8e8 Hide user dot and track own user marker in Live Location mode. (#5707)
* added a new tracking mode for following a marker and the logic for switching such tracking mode

* implemented the follow marker tracking mode

* improved and added new tests
2026-06-05 13:51:57 +02:00
Stefan Ceriu 3b1d418ff1 Correctly handle user profile dismissals in the RoomMembersFlowCoordinator
A user profile screen presented from the root of the MembersFlowCoordinator would
go back to the initial state when dismissed. Unfortunately this wasn't being handled
(like in the roomMemberDetails case) and would lead to the FlowCoordinator not
finishing itself.

Both cases now go to the initial state and that's what triggers the finished call.
2026-06-05 13:49:34 +03:00
Michael b2de4dd81d Render user and room alias links in a room's topic view (#5709) 2026-06-05 11:24:59 +01:00
mredig d66a968afd Connect settings app route and action from logout screen 2026-06-03 08:25:50 +03:00
Stefan Ceriu f040964d3f Allow the user to forward the same message to multiple rooms at once
This will send the item to the rooms in order they were chosen and only deep link
into the target room if single, otherwise it will just dismiss the forwarding screen
after sending.
2026-05-29 14:27:42 +03:00
Mauro 7093d966b4 Set map tiler URL from well known if available (#5633) 2026-05-28 15:24:58 +02:00
Doug fa67713726 Run SwiftFormat. 2026-05-27 17:11:42 +01:00
Stefan Ceriu da9eda80cd Use Compound icons within the user indicators. 2026-05-27 14:30:11 +03:00
Doug 86b51fb104 Remove the CertificateValidatorHook. (#5624) 2026-05-22 15:26:54 +01:00
Stefan Ceriu ac20ff0fc3 Forward current composer text to the media upload preview screen as captions 2026-05-22 16:46:42 +03:00
Michael dd0de4d7b0 Custom Notification Tones (#5527)
* added foundation for custom notifications

* feat: add localizations for tone names

also, if available, include the pro sound in the element x sound list

* use a static file location to store the notification tone

and update the file at that location when selected

* if there's a problem previewing or setting the alert tone, toast the user with the error

* rename tone directory

* create NotificationToneManager to handle tone business logic

* conform to project formatting

* assign custom sound to actual notifications

* dry up notification generation in the nse

* add compilation condition for including notification alert tone and remove from share extension

* swift format had some opinions

* flatten the notification tone ui, removing system/elementx designations

* fix stored file url breaking due to sandbox path changes

* tone manager can import custom tones and provide a list of imported tones

* ui support for custom tones

* can delete custom imported tones

* sort the custom tones

* add additional preset sounds

* can choose caf files for custom sounds and fix location persistence issues

* store sound locations with relative links

this is a better solution than storing bookmarks since bookmark resolution can be variable and differ from freshly derived urls

* add docs for new notification features

* run tone conversion in background

* resolved several ai found issues

* added protocol and mocks for notification tone manager

* added tests for notification settings screen vm interactions with the tone manager

* add tests for notification tone manager

* rename element tone names per feedback

* move custom tone option to the top of the notification tone list

* rename Tone to Sound for consistency with Android

* remove additional bundled tones

* restore accidentally deleted Element Default sound file

* system alert tones are filtered by what's available on the system prior to finalizing the collection

* Add a couple more caf file conversion log statements

* Simplify the notification sound conversion logic

* Update notification sound strings in sync with Android

* update xcodeproj after rebase

* remove conditional compilation and include NotificationAlertSound in share extension

* Use AudioPlayer instead of custom tone previewer and remove the previewer

* rename NotificationTone

* Consolidate and move errors to top of NotificationToneManager

* tone manager no longer depends on userinterfacecontroller

* Move static Tone properties to NotificationToneManager

* resolve view model initializer feedback

* update xcodeproj

* fatalerror when tone manager cannot init

* Remove banner icon on alert tone error

* fixup review feedback

* Moved URL handling to NotificationToneManager
2026-05-20 15:40:34 +03:00
Michael 5a07c98afc Make AnalyticsService mockable via `AnalyticsServiceProtocol (#5599)
* 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
2026-05-20 08:23:58 +03:00
Mauro 6c0aaa7a58 Invite the DM recipient to a new room (#5588)
* 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
2026-05-18 10:08:07 +02:00
Mauro Romito 07fc022a65 prevent replies to LLS timeline items, and live location sharing in threads 2026-05-12 17:26:02 +02:00
Doug e235e3ba81 Link new device with QR code tweaks. (#5563)
* Hook up Rust's InvalidCheckCode failure to the right state when linking a new device.

* Automatically regenerate a new QR code instead of ending the flow when it expires.
2026-05-11 14:22:34 +01:00
Doug 0355e9f708 Add an OAuthPresenterHook. (#5545)
* Add an OAuthPresenterHook.

* Update the enterprise submodule.
2026-05-06 10:29:25 +01:00
Doug 0acbc41432 Rename OIDC to OAuth. (#5525)
* Rename OIDC to OAuth.

* Update the enterprise submodule.
2026-05-05 14:07:06 +01:00
Doug fef942f529 Restore the .oidcCallback route for external authentication. (#5391)
* Restore the .oidcCallback route (partially reverts #3461) for external authentication.

* Make sure OIDC also works for non-http URLs.

* Remove oidcAuthentication from the state machine.

There isn't a reliable way to detect failure/cancellation when e.g. the user returns from an external app without interacting with the MAS page.
2026-05-05 12:47:07 +01:00
Doug 9015c3e483 Fixes for multi-window support. (#5528)
* Correctly handle the re-opening of the main window.

Add an additional safe-guard to ensure only one main window exists.
Make sure all secondary windows use the correct tint colour.

* Fix a bug where the settings screen isn't shown on macOS when the AppLock feature is enabled.
2026-05-01 14:44:04 +01:00
Stefan Ceriu 0ec114d2f3 #5504 - Add logs around route handling and the global search window presentation 2026-04-30 13:00:35 +03:00
Doug 63592e48c1 Remove support for handling SPA calls within the app. (#5515)
* Remove support for handling SPA call links.

They were a stop-gap solution whilst we were building support for embedded room calling.

* Simplify ElementCallConfiguration now that there is only 1 type of call to handle.

* Remove the unused overlayModule from NavigationRoomCoordinator.
2026-04-29 19:32:38 +01:00
Doug 0087b5a4e5 Fix a bug where the onboarding flow was dismissed by logging out. (#5481)
* Fix a bug where the onboarding flow was dismissed by logging out.

* Add some tests for the available actions while we're here.

---------

Co-authored-by: Stefan Ceriu <stefan.ceriu@gmail.com>
2026-04-27 14:33:09 +01:00
Mauro Romito 876109ef75 removed LLS feature flag 2026-04-27 15:13:07 +02:00
Doug 95c32225a8 Add a Developer Options button to the AuthenticationStartScreen on Nightly builds. (#5472)
* Add a Developer Options button to the AuthenticationStartScreen on Nightly builds.

* Make sure the Developer Options are actually shown in the settings screen on Nightlies.
2026-04-23 15:52:47 +01:00
Valere Fedronic d49a6e5a5d Support for ongoing voice vs video call + joining (#5399) 2026-04-21 09:11:52 +00:00
Stefan Ceriu 8f0f652420 Fix various warnings 2026-04-17 10:55:48 +03:00
Mauro 602d779e3a Render LiveLocations in the map (#5394) 2026-04-14 18:27:34 +02:00