Applies the HealthChat product identity through the fork seams upstream already
provides, so no upstream logic files are touched and merges stay clean.
- Variants/HealthChat/healthchat.yml holds the identity scalars (display name,
bundle id ch.healthchat.element, app group, development team) and is included
permanently from project.yml. APP_NAME stays ElementX so the module name and
@testable import ElementX keep working.
- ElementX/Sources/AppHooks/HealthChat/ registers an AppSettings hook pinning
accountProviders to healthchat.ch with other providers disabled, push through
sygnal.healthchat.ch and a custom-scheme OIDC redirect; plus a Compound hook
recolouring the accent token family to the HealthChat blue.
- Entitlements are edited directly in ElementX/SupportingFiles/target.yml rather
than in the variant, because XcodeGen concatenates arrays on include-merge and
a variant can override scalars but cannot remove array entries. Drops the
Element Classic app group and keychain group, and narrows associated domains
to app.healthchat.ch, keeping matrix.to for permalinks.
- Info.plist CFBundleName now follows APP_DISPLAY_NAME — it, not
CFBundleDisplayName, is what the web authentication sign-in alert shows.
- App logo and app icon assets swapped in place; the onboarding welcome title
moves to a new screen_onboarding_welcome_title_ios untranslated string.
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.
* 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.
* 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>
* 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>
* 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
If the user attempts to invite someone (to a room or creating a DM) whose identity is not cached, we prompt them to make sure this was their intention.
* Implement voice message variable playback speed
* Move playback speed string to Untranslated
https://github.com/element-hq/element-x-ios/pull/5121#discussion_r2822631371
* Address review feedback for voice message playback speed
- Persist voice message playback speed as an enum in AppSettings instead of storing an index.
- Update playback speed cycling to derive from enum allCases and safely fall back to `.default` if the stored value cannot be resolved.
- Apply runtime speed updates in AudioPlayer only when the player is in the `.playing` state.
- Keep MediaPlayerProviderTests formatting/indentation style intact while retaining mock playback speed setup.
- Regenerate preview snapshots for:
- PlaybackSpeedButton
- VoiceMessageRoomPlaybackView
- VoiceMessageRoomTimelineView
* Move VoiceMessagePlaybackSpeed outside AppSettings, remove speedRatio
* Stabilize PlaybackSpeedButton width
* Sync voice-message speed label
- Add voiceMessagePlaybackSpeed to TimelineViewState and bind it from appSettings.$voiceMessagePlaybackSpeed.
- Pass that timeline-level speed into VoiceMessageRoomPlaybackView and use it for PlaybackSpeedButton, so labels update consistently across items.
- Use @EnvironmentObject in VoiceMessageRoomTimelineContent so the view re-renders when timeline context state changes.
- In WaveformInteractionModifier, add .allowsHitTesting(showCursor) to the cursor interaction view so hidden pre-playback cursor hit area does not steal taps from the speed button.
* Reorder some properties.
No code changes.
* Refactor TimelineItemSendInfo out of the styler.
* Add (unused) examples of encryption shields.
* Rename file.
* MediaUploadingPreprocessor - Prevent images without any GPS metadata from being changed
* Add support for sending images
* Add support for sending video, audio and file attachments
* Rename MediaPickerPreview to MediaUploadPreview
* Move media uploading to the MediaUploadPreviewScreen, add waiting indicators and error handling
* Add support for pasting and drag&dropping in media for upload
* Adopt new media picker source UI, remove developer flag
* Set minimum heights for timeline loadable images
* Fix invalid camera picker file names
* Fix flakey MediaUploadingPreprocessor image tests, improve gps metadata stripping
* UITests: Update existing screenshots and add new step for the room attachment picker
* Switch all github action runners to macos-13
* Cleanup enter key and paste message composer handlers
* Notifications Enabled with default static text
notifications enabled with default static text
code improvement
added the share key
* added the changelog
* notification ID is added to the json only if it exists
* renamed Bundle.mainApp to app and updated the strings from localazy
* made a struct for the APNSPayload
* APNS Payload fix
* Fixed the issue, added tests and italian translation
* changelog
* improved translation handling code and added more tests
* Update UnitTests/Sources/LocalizationTests.swift
Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
---------
Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
- room composer contextual menu for selecting source
- coordinator for presenting the different sources
- system picker handling and URL passback
- file preview after selection
- feature flag
* generated files
* Revert "generated files"
This reverts commit f62c1dbcd9e505083ad4ff17532e2c054e253187.
* renaming files to RoomMembersList
* completed the renaming of the list files
* added generated files
* basic setup of the view and the mock
* added a new mock with a avatar
* share/copy link
* copyUserLink implemented
* removed unimplemented tests
* block user UI
* navigation to room member details added
* implemented but we require a sync from the Rust side
* adjusted some UI test screens
* alert for unblocking
* completed
* some tests
* changelog
* some unit tests
* improved the tests
* removed unused comment
* Update ElementX/Sources/Services/Room/RoomProxy.swift
Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
* optional displayName
* removing toggle
* removed cancel title
* Update UnitTests/Sources/RoomMemberDetailsViewModelTests.swift
Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
* removing Group
* pr suggestion
* better naming
* removed capitalizingFirstLetter
* Update ElementX/Sources/Other/Extensions/Alert.swift
Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
* trailing closure
* removed useless catch clause
* naming conformed to ignore
---------
Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
* add start chat flow with UI
* add feature flag for start chat
* add changelog
* fix naming and tests
* fix empty display name in user cell
* Update ElementX/Sources/Application/AppSettings.swift
Co-authored-by: Alfonso Grillo <alfogrillo@element.io>
* add screenshots from UI test
* fix swiftFormat and add identifiers
* fix warnings
* add the create or open already existing direct room feature
* add changelog
* add UserProfile object, add loading indicator in start chat flow
* fix test
* add new section for user profile in start chat
* fix duplicates input on search bar
* Update ElementX/Sources/Services/Client/ClientProxy.swift
Co-authored-by: Alfonso Grillo <alfogrillo@element.io>
* Update ElementX/Sources/Services/Client/ClientProxy.swift
Co-authored-by: Alfonso Grillo <alfogrillo@element.io>
---------
Co-authored-by: Alfonso Grillo <alfogrillo@element.io>
* created the row in the view and the alert, and added the new function to the RoomProxy
* fixed an issue with the alert function
* handling the navigation
* fixed a bug with the detail coordinators being dismissed incorrectly when inside a stack
* implementation completed
* replaced UI screenshots
* added a test for the fixed bug of the coordinators
* trying to increase the wait time for the expectation
* improved the test
* improved the buttons UI
* uploading artifacts for unit tests
* added result bundle true
* improved the tests
* added a new test
* pr suggestions
* updating mock
* PR suggestions
* improved tests
* fixed UI tests
* pr should be ready now
* removed testing code
* reduced complexity
* fixed test
* added a an assert to the new test case
* more tests and messages cases
* pr comments addressed
* completed
* created the empty files
* set up the view content
* connected the Room Coordinator to the ReportContent Coordinator
* added the loading indicators and the dismiss behaviour
* almost completed but I need to display the success indicator when the report is sent succesfully
* completed
* added an untranslated string
* tests
* Update ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift
Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
* Update ElementX/Sources/Screens/ReportContent/View/ReportContentScreen.swift
Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
* pr comment
* pr suggestion
* removing unused identifiers
* fixing compilation error
* added a form text editor view
* changelog
---------
Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
Squashed commits:
[42e45fc] Even more tweaks following code review
[5dcd5be] Add swift-algoritms and switch bubbling detection to its `chunked` method
[4ac70ed] Move the groupBy implementation to Collection instead of Array
[6aeffc3] Tweaks following code review
[0ca5ac2] Bubbles working again, grouping computed closer to the UI level
[3a66030] Refactor how timeline items are built in the RoomTimelineController
[57d51e9] Remove grouping from timeline items
[8608950] Remove the RoomTimelineViewFactory, update the GroupRoomTimelineView
[9e52e61] Add array grouping extension, unit tests and switched the timeline controller to it
[7d213a1] First attempt
[90bb1d7] Remove now unused `RoomTimelineController` `updatedTimelineItem` calback
* 127 Attach Screenshot in Bug Report Screen
* #127 code improvement
* #127 Code improvements, and changed the loading... label to sending...
* using a statically defined identifier for the new defined ui element
* added the RowLabelStyle and improved the design of the view
* code improvement
* code improvement
* making alignment private
* synthesised init
* Automatic discovery of the sliding sync proxy.
* Handle homeserver detection from a MXID.
* Update sliding sync info link, SDK and bump patch.
Add a migration on the new version. The change in restoration token format requires the user to sign in again, but this will fail with the existing device ID.
- Decryption banner on the timeline
- Bubble colours
- Background insets
- Multiline composer corner radius
- Read marker
- GIF indicator
- Reactions shape
- Use RoomTimelineViewLabelStyle everywhere possible
- Only set a line limit on reply quotes, allow all the lines for regular quotes.
- Message label icons
- Yes/No button casing
- Make sender profiles immutable.
- Enable copy link and invite buttons.
- Fix layout loop detecting multiline composer text.
- Add animation to the encryption banner.
* State events in the timeline WIP
* Implement membership change strings.
* Add other state event types and use in RoomSummaryProvider.
Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
* Cleanup session verification state machine configuration
* Add support for new timeline items: loading indicators, stickers and invalid/unsupported events
* Add sticker accessibility label, fix session verification ones
* Add support for the new TimelineStart timeline item and new pagination API. Remove identifiers from individual timeline items and only set them in the TimelineTableViewController
* Add changelog