Commit Graph

742 Commits

Author SHA1 Message Date
Valere Fedronic 0f72fe3511 Add support for active call item rendering in timeline (#5775)
* feat(timeline): Add support for active call item rendering in timeline

* Update active call as per design (show raw count of members)

* fixup project files

* revert unexpected generated mocks change

* code review

* Record preview snapshots

* revert changes on project.yml

* post rebase fix
2026-07-22 15:13:46 +01: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
Doug a6466e80e0 Update the SDK and use RoomHero.status and subscribeToOwnProfile. (#5905)
* 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.
2026-07-22 12:18:02 +01:00
Mauro 9093631f8b Periphery cleanup (#5893) 2026-07-20 11:16:11 +02:00
Jürgen Wischer 99ba9eb235 Fix CI failures: SwiftFormat indentation and stale text field snapshot
Reformat two files to satisfy SwiftFormat's indent rule on blank lines
introduced by the accessibility fixes in this branch, and re-record the
compoundTextFieldStyle preview snapshots to match the new resting-state
border rendering on raised text fields.
2026-07-17 14:14:45 +02:00
Jürgen Wischer c4f38cf1b2 Use accessibilityValue(_:isEnabled:) instead of an empty-Text fallback
Avoids applying an empty accessibility value when there's only one
pinned item, per review feedback.
2026-07-17 14:14:45 +02:00
Jürgen Wischer 60cd7fd5cc Give the pinned items banner an explicit accessibility label and value
The view-all button drops its visible text to an empty string while
loading, relying only on a ProgressView for feedback, so VoiceOver
users focusing it while it loads hear an unlabelled button. The main
pinned-item button also has no accessibility label/value describing
which pinned item is shown or its position, since children: .contain
leaves that to implicit merging of its sub-views. Set an explicit
label on the view-all button so it always announces its title, and
give the main button an explicit label (the pinned message) and value
(its position, reusing the existing bannerIndicatorDescription/
screenRoomPinnedBannerIndicator strings) instead of relying on
container merging.
2026-07-17 14:14:45 +02:00
Jürgen Wischer 7f5876c079 Expose formatting toolbar buttons as toggle controls to VoiceOver 2026-07-17 14:14:45 +02:00
Doug e80717f63d Show user statuses in mention suggestions. 2026-07-10 17:59:42 +01:00
Doug 01b946926f Show user statuses in the DM room header. 2026-07-10 17:59:42 +01:00
Mauro 0a77ba6c90 Swift format enforce isEmpty rule (#5843)
* swift format enforce isEmpty rule

* revert scheme

* use trailing closure
2026-07-06 15:39:16 +02:00
Mauro d2ef1e71f9 Remove the "unflip" of the timeline when in voice over mode (#5835)
Keep the timeline as it is in voice over mode, and don't "unflip" it
2026-07-06 14:00:53 +02:00
Stefan Ceriu 122a0052ae Drop the unnecessary @Sendable from the composer attribute enumeration
`NSMutableAttributedString.enumerateAttribute(_:in:options:using:)` runs its
closure synchronously on the calling thread and its `using:` parameter isn't
`@Sendable`. The explicit `@Sendable` on the closure literals was therefore
unnecessary and was the only thing triggering the "capture of non-Sendable
NSMutableAttributedString" and "mutation of captured var in concurrently-
executing code" warnings. Removing it clears all six with no behaviour change.
2026-06-29 18:10:30 +03:00
Doug f05fd41c36 Replace the UserPreference property wrapper with the new macro version. 2026-06-29 10:34:32 +01:00
amshak 9f92e181b0 Added a chevron to collapsed call buttons in the DM (#5755)
* Added a chevron to collapsed call buttons in the DM

This makes the context menu more intuitive and easy to find. Inspired by the collapsed state of call buttons in Whatsapp that I saw recently

* Shortening video/voice call button strings

Currently the text is unnecessarily long, I have reduced to button text

# Conflicts:
#	ElementX/Sources/Generated/Strings+Untranslated.swift

* Move translations to localazy

---------

Co-authored-by: Stefan Ceriu <stefan.ceriu@gmail.com>
2026-06-22 13:23:37 +03:00
Mauro Romito 3aedd0ccff swiftformat now enforces newlines for ifs 2026-06-19 15:28:27 +02: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
Stefan Ceriu 3d90a43175 Wrap selected text in a markdown link when pasting a URL over it
Pasting a single link on top of a selection in the message composer now
produces a markdown link, e.g. selecting "Google" and pasting
"google.com" yields "[Google](google.com)". Non-link clipboard
contents and pastes without a selection keep their existing behaviour.
2026-06-16 13:15:04 +03:00
Mauro Romito 6ec1f0eb10 swiftformat 2026-06-08 13:36:03 +02:00
Doug 32ccb004d0 Re-order the call buttons to match the Figma and Element Web. (#5696) 2026-06-03 11:53:49 +01:00
Stefan Ceriu 6ad1654d97 Convert the old MockTimelineController to the generated TimelineControllerMock 2026-06-03 08:57:04 +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
Doug 08d02001bf Tidy up mock creation. (#5627)
* Use our standard XYZMock(.init()) pattern everywhere instead of XYZMock.default.

* Remove the configuration parameter label on mock convenience inits.

* Update the enterprise submodule.
2026-05-22 17:34:35 +01:00
Stefan Ceriu 77c5aba326 Forward current composer text to the new poll form to serve as the question/topic 2026-05-22 16:46:42 +03: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 22d14ff8e4 AppSettings are Mockable (#5589)
* create DependenciesProtocol and replace ServiceLocator registration with it

replace mocking calls for ServiceLocator to Dependencies

replace ServiceLocator with instance level calls

replace ServiceLocator configs with TestDependencies config in Tests

replace servicelocator usage in analytics service

replace remaining ServiceLocator calls in unit tests

that depended on the UnitTestAppCoordinator configuration with per suite dependencies instances

fix swiftlint warning

remove remaining references to ServiceLocator

make dependencies properties consistent in tests

delete Dependencies and DependenciesProtocol

fix whitespace modifications

updates from PR feedback

a pass over converting AppSettings and AnalyticsService test instance properties to per test instantiation

fix a missed PR feedback

Sync up after rebase

create DependenciesProtocol and replace ServiceLocator registration with it

replace mocking calls for ServiceLocator to Dependencies

replace ServiceLocator with instance level calls

replace ServiceLocator configs with TestDependencies config in Tests

replace servicelocator usage in analytics service

replace remaining ServiceLocator calls in unit tests

that depended on the UnitTestAppCoordinator configuration with per suite dependencies instances

fix swiftlint warning

remove remaining references to ServiceLocator

make dependencies properties consistent in tests

delete Dependencies and DependenciesProtocol

* AppSettings is instance level mockable now

* replace mocked and preview usages of reset + AppSettings global init with

AppSettings(store: UserDefaultsMock())

* AppSettings.UserDefaultsKeys is now a RawRep struct, making it extensible

* update tests with new AppSettings so it builds

* update remaining AppSettings test/mock inits

* AppSettings.UserDefaultsKey conformed to ExpressibleByStringLiteral

* addressed issues found in first pass ai review

* update AppSettings instantiations after rebase

* fix accessibility tests coordinator after rebase

* Rename to VolatileUserDefaults

* AppSettings init uses mandatory parameter

* Revert UserDefaultsKey to enum

* Add TrackedUserDefaults to be able to reset the defaults object

* Added volatile static func to AppSettings

* Use .volatile() static func instead of full init

* review fixups

* Resolve build issues after rebase

* updated enterprise module

* remove the static reset settings call from the preview tests

---------

Co-authored-by: Mauro Romito <mauro.romito@element.io>
2026-05-22 15:14:08 +02:00
Stefan Ceriu 14f7f4a6bb Fix small multiple_closures_with_trailing_closure warning 2026-05-21 17:59:04 +03:00
Danny eae464ecd7 Timeline: add a Jump to Unread button and a new-message badge on the scroll-to-bottom button. (#5506)
* Timeline: add a Jump to Unread button and a new-message badge on the scroll-to-bottom button.

* Rename scrollToFirstUnread to scrollToReadMarker for consistency with isReadMarkerVisible.

* Cache readMarkerUniqueID and unreadMessageCount as stored properties on TimelineState.

* TimelineViewModel: rename newTimelineItems and drop redundant ordering comment.

* Use Compound chevron icons in TimelineScrollButton.

* Fix TimelineScrollButton layout at large dynamic type sizes.

* Add a trailingAccessory slot to topBanners and use it to dodge banners with the jump-to-read-marker button.

* Put jump-to-read-marker behind a developer-options feature flag.

* Fine-tune TimelineScrollButton sizing and badge colour.

* Remove TimelineScrollButton chevron offset that was compensating for SF Symbol centering.

* Drop the new-messages count, replace with a presence dot.

* Move both timeline scroll buttons to bottom-right and revert topBanners trailingAccessory slot.

* Position TimelineScrollButton badge above for up direction and below for down direction.

* Add long-press mark-as-read pill to the timeline scroll buttons

* Read isSwitchingTimelines from state in updateHasNewMessagesAtBottom.

* Use assertionFailure when scrollToReadMarker is called with no read marker.

* Add TimelineScrollButton preview snapshots.

* (fix) design and various self-review issues

* (fix) suppress scroll button tap after long-press

* (feat) fall back to RoomInfo.fullyReadEventID for jump-to-unread

* (fix) hide jump-to-unread immediately after mark-as-read

* (fix) align with newer matrix-rust-sdk surface

* Bump the RustSDK to v26.05.20

---------

Signed-off-by: Daniel Anderson <daniel.anderson@toptal.com>
Co-authored-by: Stefan Ceriu <stefan.ceriu@gmail.com>
2026-05-21 15:03:32 +03:00
Stefan Ceriu ab82068740 Make the AnalyticsServiceMock default a variable as well, for consistency. 2026-05-21 12:37:52 +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
Stefan Ceriu 16715ea1c2 Remove the focused ComposerToolbar accessibility test and preview
The automatically focused keyboard is creating false positives when running accessibility
tests and doesn't bring any value in the previews. Simplest solution is to remove it.
2026-05-16 16:54:32 +03:00
Mauro Romito a4a857003c use isDM from the SDK to determine if a spaceRoom, a joinedRoom or a notificationItem are from a dm room. 2026-05-14 13:47:44 +02:00
Michael ff5dcb040d Replace the ServiceLocator with direct dependency injection (#5548)
Removes the ServiceLocator singleton and instead directly injects the dependencies it was holding for more control over instantiation of the various component subtrees and better visibility over how they're being used.
2026-05-14 09:45:49 +03:00
Valere 2582293c06 call: Only group voice/video call if threads developer option is on 2026-05-12 10:39:05 +03:00
Mauro Romito d02459d9b8 limit knock FF only room creation and access type changes
# Conflicts:
#	ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift
2026-05-04 14:12:31 +03:00
Mauro 76f744b9c4 Live Location Sharing - handle server echoes (#5514)
* 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>
2026-04-30 13:18:36 +00:00
Stefan Ceriu 53a54c1b90 Allow the mac app to chose room avatars directly from files instead of the photo library 2026-04-30 14:58:08 +03:00
Mauro Romito 876109ef75 removed LLS feature flag 2026-04-27 15:13:07 +02:00
Richard van der Hoff 9a2a852af3 Promote "history sharing on invite" out of developer options (#5480)
* Enable key-share-on-invite irrespective of feature flag

* Remove feature-flag dep: warning on starting chat with new people

* Remove feature-flag dep: invite from room member details

* Remove feature-flag dep: warning on new users in invite screen

* Remove feature-flag dep: from room details screen

* Remove feature-flag dep: starting chat from user profile screen

* Remove feature-flag dep: timeline info on forwarded keys

* Remove feature-flag dep: RoomScreenModel

* Remove `enableKeyShareOnInvite` from AppSettings

* Remove `enableKeyShareOnInvite` feature flag

* Remove outdated comments

* Update preview test room snapshots as their header now includes the history sharing icon
2026-04-27 14:43:18 +03:00
Stefan Ceriu 0c91ae7869 Tweak some things, fix some things, delete some things 2026-04-24 16:44:00 +03:00
amshak 69822c8518 Combine DM call actions into one menu item
This helps give more space to the room header. Specially in the scenario when threads is enabled.
2026-04-24 16:44:00 +03:00
Mauro ef26796d98 Open Live Locations map on tapping on the banner (#5477)
* Implemented opening the LLS on our own user when tapping on the banner

* added a test for moving the map as soon as the first update arrives.

* updated preview tests
2026-04-24 13:19:07 +02:00
Valere Fedronic d49a6e5a5d Support for ongoing voice vs video call + joining (#5399) 2026-04-21 09:11:52 +00:00
Mauro 602d779e3a Render LiveLocations in the map (#5394) 2026-04-14 18:27:34 +02:00
Stefan Ceriu 7ff2cf618b Add an action to the newly introduced FloatingDateBadge that scrolls the timeline to that day. (#5350)
and replace the TimelnieTableViewController's `floatingDateText` with a pure date.
2026-04-14 11:27:27 +03:00
Mauro Romito d4abb24873 swiftformat 2026-04-13 11:40:22 +02:00
Mauro 922fcafcd5 Live Location Sharing Banner (#5370)
* Live Location Sharing Banner

# Conflicts:
#	ElementX.xcodeproj/project.pbxproj

* updated the top banner modifier and the top banner views

# Conflicts:
#	ElementX/Resources/Localizations/en-US.lproj/Localizable.strings
#	ElementX/Resources/Localizations/en.lproj/Localizable.strings

* improved the stopping function from the timeline item

* stop live location sharing before starting a new one.

* added some tests for LiveLocationManager

* pr suggestions
2026-04-10 14:50:42 +02:00
Valere Fedronic b05ab3ac0b Add support for starting voice calls from a DM (#5305)
* feat: Start voice call from DM

* rename voiceCall:bool to isVoiceCall

* review: Fix a typo

* review: use one displayCall(bool) instead of 2 actions

* review: Add a new specific preview for DM calls

* combine startCall and startVoiceCall in single enum with isVoiceCall

* review: add isVoiceCall to presentCallScreen action

* review: Use proper a11y for voice vs  video

* add voice/video options to UserProfile Screen

* fixup: move config params to the roomInfo object

* review: Revert changes on preview as the toolbar cannot be snapshot'd

* review: Extract call controls in specific file

* oups: Add voice call option in room details screen

* Update room details screenshots

* Update user profile screenshots

* Update room member details screenshots

* fixup: remove dead code
2026-04-09 16:22:31 +01:00
Mauro Romito 95f3edac7f floating date feature is now out of the feature flag 2026-04-08 14:55:07 +02:00