48 Commits

Author SHA1 Message Date
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
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
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
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 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
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
Aaron Thornburgh 96b6d69d5a Update Send button bg color (#5170)
* Update Send button bg color

Change the gradient bg to accent/rest.

* Tidy-up ComposerToolbar to match iOS 18 Figma.

Also simplifies the tests a bit.

* Add a .glassEffect to Compound's SendButton.

* Add a border to TimelineReplyView.

Also use the same sizes in both the message bubbles and the composer.

* Change icon size and container in message bubbles

- Container size = 36x36px
- Icon size = 24x24px

* Update icon of reply contents to be 24x24

* Update the VoiceMessageButton to match the designs.

* Adopt Liquid Glass in the ComposerToolbar.

* Generate and fix snapshots.

---------

Co-authored-by: Doug <douglase@element.io>
2026-03-25 17:42:10 +00:00
Stefan Ceriu 23062901c0 Update files following swiftformat upgrade 2026-01-27 12:50:57 +02:00
Mauro f7dd9cdcf8 Update copyright holding and dates (#4640)
* Update copyright holding and dates

* compound IDE Macros updated

* update copyright

* update copyrights done

* update templates and README
2025-10-21 14:34:56 +02:00
Stefan Ceriu 549a8de6a9 Rename detectPermalinks to addMatrixEntityPermalinkAttributesTo and move code around 2025-09-09 17:17:40 +01:00
Stefan Ceriu df335bd2b1 Multi file uploads (#4358)
* Allow MediaPickerScreen users to select the media selection mode (single or multiple)

* Fix cancellation

* Add support for multiple media URLs on the MediaUploadPreviewScreen.

* Support processing more URLs on the `MediaUploadingPreprocessor` and sending more on the `MediaUploadPreviewScreen`

* Add feature flag for `multipleAttachmentUploadEnabled`

* Add a label showing the current preview item index in the MediaUploadPreviewScreen

* Add support for dragging and dropping or pasting multiple items at the same time.

* Support sharing more than one file through the share extension.

* Limit the number of items that can be shared in one go to 5.

* Fix unit tests

* Fix incorrect fatal error when dealing with single selection media pickers.

* Document the `multipleAttachmentUploadEnabled` usage in the context of the MediaPicker.

* Use a task group for processing selected media in the photo library picker.

* Use a task group for processing multiple selected media in the MediaUploadingPreprocessor

* Switch the maximum number of items that can be shared to 10.

* Allow multiple items to be pasted at the same time.
2025-07-30 15:44:05 +03:00
Stefan Ceriu bfcb52ced0 Enable polls in threads as the SDK supports them now. 2025-07-24 14:55:34 +03:00
Stefan Ceriu 6fc6df9375 Refactor how drafts are handled on a coordinator level and add support for them on thread timelines. 2025-06-13 16:56:13 +03:00
Stefan Ceriu 558cdf5be3 Add support for sending media within threads.
This patch add the `threadRootEventID` as a parameter to media sending functions and forwards the timeline thread root between various application states to the place where its needed.
The 2 missing items are Locations and Polls which currently don't have any support on the Rust side for being sent within threads. That will come in a separate PR.
2025-06-10 21:20:09 +03:00
Stefan Ceriu af97567edc Move ComposerToolbar view required dependencies to the view model and read them, similarly to the other views, through the context's view state. 2025-06-10 08:57:08 +03:00
Doug 5e50823223 Allow the services that are configured by secrets to be disabled. (#3961)
* Make the map tiler key optional.

* Make the bug report URL optional.

* Make the sentry URL optional.

* Make the analytics configuration optional and handle consent taking Sentry into account.

* Stop prompting users to report crashes when Sentry is disabled.
2025-04-01 09:24:12 +01:00
Mauro Romito f248bdfd92 removed images in pills in favour of text decos
FIX

fix
2025-03-17 14:45:23 +01:00
Stefan Ceriu 07e96115ce SDK update (#3891)
* Bump the RustSDK to v25.03.11

* Replace oidc login prompt with nil following the changes from https://github.com/matrix-org/matrix-rust-sdk/pull/4761

```
/// * `prompt` - The desired user experience in the web UI. No value means
///   that the user wishes to login into an existing account, and a value of
///   `Create` means that the user wishes to register a new account.
```

* Fix trailing closure warnings

* Update the client proxy after making `getNotificationSettings()` and  `cachedAvatarUrl()` async (they used to be blocking on the rust side).

* Move `Room.isEncrypted` to the info publisher and manually update the encryption state when creating the room.

* Bump the SDK again to v25.03.12 - This introduces a new way to configure the tokio runtime that we can use to have extensions use less memory
- introduce a new Target struct that takes care of setting up rust services (tracing and tokio) for our various targets
- cleanup MXLog and friends

* Address PR comments

* Bump the SDK again, switch back to using `.consent` as the OIDC login prompt (which was reintroduced in matrix-org/matrix-rust-sdk/pull/4791)
2025-03-13 11:17:37 +02:00
Mauro 5f59e867b5 Room mentioning in the composer (#3868)
* refactored the suggestion item structure

to scale with the room pill

* Implemented a way for the rooms

to appear in the suggestions view for the RTE, however I need to add the pills to the composer and the compatibility with the plain text composer

* small code correction

* fix

* fixed a bug where the suggestion wasn't returning

the right suggestion type and the suggestion text properly

* implementation done!

also updated some tests, but we need more of them

* updated toolbar view model tests

* updated tests

* updated preview tests

* renamed the Avatars case for the suggestions
2025-03-06 11:32:37 +01:00
Stefan Ceriu 890687512f Show room encryption state in the composer (#3841)
* Fixes #3835 - Show room encryption state in the composer

* Update the preview test snapshots

* Update the UI test snapshots.
2025-02-27 22:16:26 +02:00
Vickcoo 4b43d901f8 Fix message completion trigger to work anywhere in the message (#3696)
* Fix message completion trigger to work anywhere in the message

* Add tests for display suggestion in difference message positions

* Fix suggestion trigger could support multiple mention symbol

* Remove optional parameter type and tweak argument name to hide

* Optimize the suggestions trigger using regex

* Fix the cursor at wrong position after selected suggestion

* Modify the rawSuggestionText pass data in right way

* Modify mention symbol to use regex type

* Update ElementX/Sources/Screens/RoomScreen/ComposerToolbar/CompletionSuggestionService.swift

Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>

* Update generated mock

---------

Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
2025-02-13 15:13:09 +00:00
Doug bad4a8f9c8 Refactor Rust timeline identifiers into our own. (#3731)
* Refactor eventOrTransactionID.

* Refactor uniqueID.
2025-02-04 09:50:46 +00:00
Valere f20847f62b Warn and block sending on verification violation (#3679)
* feat(crypto): Warn and block sending on verification violation

* fixup: Fix ComposerToolbar previews

* fixup! add ComposerToolBarViewModelTests for canSend

* add new preview tests for verification violations

* Use `deferFulfillment`s in the unit tests.

---------

Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
2025-01-20 18:29:34 +02:00
manuroe 3950cac085 Dual licensing: AGPL + Element Commercial (#3657)
* New LICENSE-COMMERCIAL file

* Apply dual licenses: AGPL + Element Commercial to file headers

* Update README with dual licensing
2025-01-06 11:27:37 +01:00
Stefan Ceriu caaa89af62 Media gallery - part 1(#3588)
* Introduce a `MediaEventsTimelineFlowCoordinator`
* Update SDK API and architecture
* Add a feature flag, add translations
* Move the media events timeline presentation under the room flow coordinator state machine
* Rename `TimelineViewState.timelineViewState` of type `TimelineState` to `timelineState`
* Enabled SwiftLint's `trailing_closure` rule and fix the warnings.
2024-12-06 16:58:14 +02:00
Doug 7e1476d973 Add support for adding/editing/removing media captions. (#3547)
* Add support for editing media captions.

* Add composer snapshots.

* PR comment.
2024-11-21 18:18:27 +00:00
Doug c081e538b4 Add support for sharing URLs and text. (#3546)
* Add support for sharing URLs and text.

* Fix a bug where a stored draft would overwrite the shared text.

* Add tests.
2024-11-21 14:48:38 +00:00
Doug a4ea552a83 Show a verification badge on the Room Member/User Profile screens. (#3427)
* Add a badge for verified users/room members.

* Reorder subviews.

* Add a (disabled) button to verify other users.

* PR comments.

* Update the SDK.

* Adopt the SDK changes introduced in matrix-rust-sdk/pull/4100

---------

Co-authored-by: Stefan Ceriu <stefan.ceriu@gmail.com>
2024-10-21 16:07:19 +01:00
Stefan Ceriu 35d49c4d85 Refactor theTimelineItemIdentifier handling; stop relying on optional EventOrTransactionIds and be explicit when setting composer modes from the draft service. 2024-10-16 16:37:47 +03:00
Stefan Ceriu c79dbe85a0 Bump the RustSDK to v1.0.53: adopt latest record based timeline item APIs (#3356) 2024-10-01 18:50:11 +03:00
Stefan Ceriu a4166de502 Add support for showing media playback controls on the lock screen 2024-09-09 14:42:32 +03:00
Stefan Ceriu 664e87fe87 Switch license to AGPL (#3237)
* Switch license file to AGPL

* Update file copyright headers

* Update the default project file header
2024-09-06 16:34:30 +03:00
Stefan Ceriu f89c3e54b4 Automatically try reloading failed images on network changes (#3170)
* Add the networkMonitor to the NSE and delete the old MockMediaLoader

* Generate a MediaLoaderMock through AutoMockable and use it in the MediaProviderTests

* Implement an ImageProvider mechanism that automatically tries reloading images when connectivity is established again and use it for LoadableImages

* Merge the ImageProvider protocol back into the MediaProvider

* Address PR review comments

* Provide a default sdk client request configuration

* Address tasks not automatically cancelling themselves when views get deallocated
2024-08-15 18:20:19 +03:00
Mauro 1ad361a6e8 RoomScreenViewModel is now TimelineViewModel (#3157)
Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
2024-08-13 13:36:40 +02:00
Mauro dbdea337ca Restore Mentions in plain text mode (#3018) 2024-07-09 13:02:46 +02:00
Mauro b07d85cd06 FIX: saving draft did not save the pill markdown content (#3003) 2024-07-08 15:55:13 +02:00
Mauro 94f98345b0 Volatile draft to restore the composer after an edit. (#2996) 2024-07-02 14:48:50 +00:00
Stefan Ceriu 0967bb43b4 Avoid passing the whole unsafe display name to the rich text editor for generating mention pill permalinks 2024-06-14 17:33:22 +03:00
Mauro cefa38049f Store and restore drafts (#2898) 2024-06-13 12:19:38 +00:00
Stefan Ceriu b2afa04832 Cleanup dead code after Periphery run 2024-06-11 14:38:08 +03:00
Stefan Ceriu c3571f4f4e Track when the user starts a room call and when they enable formatting options on the message composer 2024-05-30 15:42:26 +03:00
Stefan Ceriu 16fc7caa62 Fix typing indicators for the plain message composer 2024-05-27 17:04:34 +03:00
Stefan Ceriu 636274df74 Seamlessly switch for the RichTextEditor based message composer to the… (#2753)
* Seemlesly switch for the RichTextEditor based message composer to the plain one depending on whether formatting options are enabled or not.

* Address PR comments

* Fixes #2803 - Add extra padding at the bottom of the composer suggestions list

* Update preview test snapshots

* Update UI test snapshots
2024-05-08 17:57:32 +03:00
Stefan Ceriu e05e664f6d Fixes #2765 - Use the keyboard up arrow to edit the last message, use escape to cancel editing or replying. 2024-05-07 14:38:37 +03:00
Stefan Ceriu 38416dbb5c Plain composer suggestions and pills (#2751)
* Move ComposerToolbar files to withing the RoomScreen folder (as it's not a screen on its own)

* Switch the plain composer to NSAttributedStrings

* Enable suggestions on the plain composer

* Introduce a new `MatrixUserDisplayName` attributed string attributed and use it for mention building

* Implement mention pill rendering and sending on the plain message composer

* Fix plain composer snapshot tests

* Fix broken formatting options layout

* Add clarifying comment.
2024-05-03 10:06:16 +01:00