* 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>
* 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
* Add a common .inverseMask view modifier and use a blend mode for efficiency.
This also fixes the snapshot rendering 🎉
* Add support for the status emoji on the app's Setting button.
* Align the room header decoration icons with the status emoji.
* Add missing snapshots.
The search screen previously ran both the room filter and the (slow) message
query on every keystroke regardless of which tab was active, so the fast room
results were held up behind message search.
Now only the active tab is searched, and the other tab is (re)searched when it
becomes active, but only if the query actually changed since it last ran,
tracked per-tab in searchedQueries. Room search reacts to every keystroke while
message search keeps the 250ms debounce, now applied inside the messages branch
of updateFilter rather than upstream of both.
* 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.
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.
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>
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>
The mechanism has been running on nightly and debug builds since it was
introduced and Sentry shows the matrix-rust-sdk#6366 background teardown
panic (SwitchGuard::drop) occurring far less on nightly than on production.
Flip the default on for release builds too so store users get the fix.
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.
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.
* 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.
* Update the SDK and handle API breaks.
* Rename sdkUserThing to rustUserThing for consistency.
* Add user status ClientProxy methods.
* Rename UserStatus.UserSet to UserStatus.Raw.
* Fix CurrentValuePublisher.map dropping updates when the mapped publisher is chained inline
The eager implementation bridged through a second CurrentValueSubject fed by
a sink whose AnyCancellable was stored on the returned struct. Combine
consumes publisher structs when building a subscription, so chaining the
mapped publisher inline (e.g. `publisher.map { … }.removeDuplicates(…)
.sink { … }`, as RoomScreenViewModel and RoomDetailsScreenViewModel do for
knock requests) dropped the only copy holding that cancellable: the feeding
sink was cancelled and subscribers only ever received the initial value.
In practice this meant a room admin viewing a knockable room never saw the
"wants to join" banner (or a live "Requests to join" badge) for a knock
arriving while the room was open — it only appeared when the knock predated
opening the room. Caught by a live cross-client knocking test; the
double-execution of the transform at subscription time (eager transform +
current-value replay) was the giveaway.
Make map lazy instead: keep the transformed AnyPublisher and a value
provider, so subscribers attach straight through to the source subject (which
replays its current value itself) and no keep-alive is needed. Adds a
regression test chaining a mapped publisher inline.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* swiftformat
* better docs
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Mauro Romito <mauro.romito@element.io>
* Use dark theme for element Call
* Make sure only the call screen is shown in dark mode.
Otherwise when you go into PiP the entire app has become dark.
---------
Co-authored-by: Doug <douglase@element.io>
* implemented checkSourceSafetyIfNeeded in the timeline media preview
* added a subtitle to the spinner when scanning and an animated drag gesture for the error and loading states
* pr suggestions
* pr suggestions part 2
* Allow the AppIconBanner tool to be called with purely the build number.
And use that for the Element Pro Nightly.
* Use a build setting to determine Nightly builds.