83 Commits

Author SHA1 Message Date
Doug e80717f63d Show user statuses in mention suggestions. 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 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 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
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
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
Mauro 26bfa6ed7c Compound - Swift 6.2 and Main actor isolation (#5109)
* compound is now using 6.2 and main actor isolation + some tweaks to make it build tests and EX

* better handling of the nonisolated context for CompoundUIColors

* improving docs

* fix comment

* remove unused Sendable conformance
2026-02-16 10:19:12 +00:00
Stefan Ceriu 37ee5c9c7e Fix a couple of warnings 2026-02-02 10:37:21 +02: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
Doug 6377d9be67 A couple of small tweaks. (#4569)
* Stop ignoring the safe area with the suggestions view.

They weren't visible on iPad (hidden behind the sidebar) and I can't find any instance when they're shown where the safe area comes into play.

* Make sure the room list deselects the cell when dismissed a room.

* Use the backports pattern in more places.

* Fix the annoying header on macOS.

* Silence some warnings

* Fix compound CI branch name.
2025-10-03 12:09:17 +01:00
Doug 2f2e6f6226 Revert weak media provider (#4483)
* Revert "Address the real lifetime issue of the SDK's `Client` by making `Context.mediaProvider` weak. (#4466)"

This reverts commit c794144ef1.

* Better docs.
2025-09-08 17:48:58 +01:00
Doug c794144ef1 Address the real lifetime issue of the SDK's Client by making Context.mediaProvider weak. (#4466)
This reverts commit 927aea4bfe.
2025-09-05 17:18:14 +00: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 82c7dfe28d Update message composer design for unencrypted rooms (#4361)
* Update message composer design for unencrypted rooms.
* Move the encryption banner to the composer toolbar.
2025-07-28 19:21:13 +03:00
Stefan Ceriu bfcb52ced0 Enable polls in threads as the SDK supports them now. 2025-07-24 14:55:34 +03:00
Mauro Romito 5905bc1e76 increas hit area for the media preview upload warning, and hide accessibility for the avatar in the mention suggestions view 2025-07-21 20:11:18 +02:00
Doug 030a9bfbef Update and enable the new bloom style on the home screen. (#4291)
* Update Compound

* Adopt the new accent colour (and gradient) tokens.
2025-07-07 11:23:03 +01:00
Stefan Ceriu d2bfcf81d2 Attempt to fix message composer layout crashes when running as an iPad app on MacOS 2025-06-27 11:09:55 +03:00
Mauro Romito d2b38a4cbe Used the close formatting option a11y label 2025-06-26 12:35:55 +02:00
Stefan Ceriu 93cd1401cf Fix preview test crashes when accessing misconfigured draft service mocks 2025-06-13 17:42:40 +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 f66d654820 Allow sending locations within threads
This patch implements support for sending locations within threads by following a similar behavior to the other screens: pass the thread root between the various state machine states until the action is finally invoked.
2025-06-12 16:54:53 +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
Stefan Ceriu 4072031f4e Move composer specific designs to the composer toolbar. 2025-06-10 08:57:08 +03:00
Stefan Ceriu 806d676299 Introduce a TimelineItemThreadSummary object (#4032)
* Introduce a `TimelineItemThreadSummary` object to hold details about threads starting from that particular item

This patch introduces a thread summary object that will be available on main timeline messages that are the root for a given thread.
It currently provides the latest message content and sender for that thread but it will grow to provide info on the number of replies, unreads etc.

It also add a new UI component called `TimelineThreadSummaryView` that makes use of this data and is in turn used by the bubbled styler to render it in the timeline.

The rest of the PR is about refactoring on the `RoomTimelineItemFactory` so that replies and thread summaries use similar paths and builders.

* Add a feature flag for threads

* Address PR comments

* Converge on single implementation for message previews
2025-04-16 16:19:29 +03:00
Doug a5d94a0219 Adopt the new start chat button design. (#4013)
* Update compound and handle plain to tertiary/textLink button style updates.

* Update the start chat button to use the right icon/style.

* Update preview snapshots.

* Fix remaining snapshots.
2025-04-11 17:09:57 +01: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 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 56d8af1d2e Only show a badge in the composer if the room is unencrypted. (#3866)
* Partially revert the message composer encryption badges and only show it for unencrypted rooms.

* Update preview test snapshots.

* Update UI test snapshots.
2025-03-04 14:58:15 +02: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
Stefan Ceriu fb8d69dd92 Fixes #3830 - Editing messages not placing the cursor at the end of the text 2025-02-26 10:56:15 +02:00
Stefan Ceriu e8786be6cd Fix #3794 - Stop the message composer from randomly changing the cursor position 2025-02-17 12:28:43 +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
Doug b477a32d2e Remove unused/redundant assets. (#3702)
* Remove unused image assets.

* Remove unused/redundant colour assets.
2025-01-27 11:44:39 +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
Doug 4966083b58 Add new development assets and use in mocks/previews. (#3581) 2024-12-03 17:14:05 +00:00
Doug c8627cfd64 Add support for copying a caption. (#3563)
* Add timeline item action for copying a media caption.

* Fix the action colours when long pressing a timeline item.

Nice side effect: Reasonable sized buttons when button shapes are enabled.

* Re-arrange the Timeline Item Menu.

* Add timeline item menu snapshots for media items.
2024-11-29 12:26:59 +00:00
Doug 751be7b3a7 Update the SDK. (#3565)
* Update the SDK.

* Add mockMXC URLs to fix all the crashes during tests.

* Refactor Voice Messages to not use a MediaSource for local files.
2024-11-28 08:34:38 +00:00
Doug 03aaf849ee Update how file captions are rendered (#3554)
* Update the File/Audio captions layout to match Figma.

* Fix caption sizing issues.

The send info label was being added incorrectly.

* Update icon size and regenerate snapshots.

* Fix a regression in the location timeline item layout.
2024-11-26 10:36:46 +00:00