Commit graph

2166 commits

Author SHA1 Message Date
11ebaf5042 fix(wallet): resolve sealed interface inheritance issue
TimelineItemEventContent is a sealed interface in messages:impl, so external
modules cannot add implementers to its hierarchy.

Solution: Create TimelineItemPaymentContentWrapper in messages:impl that
implements the sealed interface and wraps the wallet API's payment content.

Changes:
- Remove inheritance from TimelineItemPaymentContent (wallet:api)
- Add TimelineItemPaymentContentWrapper (messages:impl)
- Update TimelineItemContentFactory to wrap payment content
- Update TimelineItemEventContentView to use wrapper
2026-03-27 12:29:12 -07:00
06a9c6b0d2 fix(wallet): resolve audit findings - DI typos, missing dependency, event type consistency
FIXES:
1. Fix Metro DI package typo: dev.zacsweeny.metro → dev.zacsweers.metro
   - KoiosCardanoClient.kt
   - DefaultTransactionBuilder.kt
   - PaymentStatusPoller.kt
   - WalletModule.kt

2. Add missing dependency: features:messages:impl now depends on features:wallet:impl

3. Standardize event type: Use 'co.sulkta.payment.request' consistently
   - Updated TimelineItemPaymentContent.EVENT_TYPE
   - Updated test assertion

4. Fix DI scope inconsistency: PaymentStatusPoller now uses SessionScope
   (was AppScope but depends on SessionScoped CardanoClient)

5. Fix mixed DI annotations in DefaultPaymentEventSender
   (was mixing Anvil + Metro, now uses Metro consistently)
2026-03-27 12:11:45 -07:00
f2b95d6b8a fix(wallet): replace text-marker hack with proper raw event API (room.sendRaw + MsgLikeKind.Other)
- Add Timeline.sendRaw() to send custom Matrix events
- Add CustomEventContent type for receiving custom events
- Update TimelineEventContentMapper to handle MsgLikeKind.Other
- Update TimelineItemContentFactory to intercept payment events
- Rewrite DefaultPaymentEventSender to use sendRaw instead of text markers
- Update TimelineItemContentPaymentFactory to parse raw JSON
- Remove text-marker detection from TimelineItemContentMessageFactory
- Update tests to use raw event API
- Mark raw event SDK blocker as RESOLVED in BLOCKERS.md

Event type: co.sulkta.payment.request (reverse-domain format)
Status updates: co.sulkta.payment.status

Benefits:
- Proper Matrix protocol compliance
- No JSON embedded in text messages
- Events won't be indexed by search
- Clean separation from regular messages
2026-03-27 11:45:12 -07:00
adee67cf0d feat(wallet): payment card timeline item and raw event handling (Tasks 7+8)
Task 7: Timeline Payment Card
- TimelineItemPaymentView integration with TimelineItemEventContentView
- Payment card rendering for both sender and recipient perspectives
- Unit tests for TimelineItemPaymentContent

Task 8: Raw Event Handling
- Modified TimelineItemContentMessageFactory to intercept payment events
- Added isSentByMe parameter propagation through content factories
- FakePaymentEventSender for testing
- Unit tests for TimelineItemContentPaymentFactory

SDK Limitation Workaround:
Since matrix-rust-sdk doesn't expose raw event sending or UnknownContent
raw JSON, payment events are encoded as text messages with a marker:
[cardano-payment:v1]{...json...}

This falls back gracefully for non-wallet clients while enabling
rich payment card rendering for wallet-enabled clients.
2026-03-27 11:08:03 -07:00
39561e1aeb feat(wallet): payment flow UI — entry, confirmation, progress screens (Task 6)
Implements the payment flow UI for the Element X ADA wallet:

## Screens
- PaymentEntryScreen: Amount/recipient input with pre-filling from /pay command
- PaymentConfirmationScreen: Transaction details with fee estimation (FLAG_SECURE)
- PaymentProgressScreen: Submission status with polling for confirmation

## Features
- Biometric authentication before payment confirmation
- Matrix user detection with 'hasn't linked wallet' inline message
- CardanoScan explorer link for transaction viewing
- Testnet warning banner
- Insufficient funds detection

## Wire-up
- MessageComposerPresenter intercepts /pay commands
- SlashCommandParser integration for command detection
- Navigation to PaymentFlowNode on valid /pay command
- Snackbar error on parse errors

## Technical
- Circuit presenter pattern with Molecule/Turbine tests
- @PreviewsDayNight for all Composables
- Metro DI integration
- Fake implementations for testing

Includes PaymentEntryPresenterTest, PaymentConfirmationPresenterTest,
PaymentProgressPresenterTest with comprehensive coverage.
2026-03-27 11:04:41 -07:00
db4c262b27 feat(wallet): /pay slash command parser and composer integration (Task 5)
Implements Task 5 of Phase 1:

New files:
- ParsedPayCommand.kt: Sealed interface for parse results
  - WithAddressRecipient: Pay to Cardano address
  - WithMatrixRecipient: Pay to Matrix user (requires lookup)
  - AmountOnly: Amount specified, prompt for recipient
  - Empty: Open payment flow with no prefilled data
  - ParseError: Parse error with human-readable reason

- SlashCommandParser.kt: Full /pay command parser
  - Handles: /pay, /pay 10, /pay 10 ADA, /pay 10 tADA
  - Matrix recipients: /pay 10 ADA @user:server
  - Cardano addresses: /pay 10 ADA addr1...
  - Validates amounts (decimal support, max supply check)
  - Validates addresses (prefix, length, network match)
  - Comprehensive error messages

- SlashCommandParserTest.kt: 40+ unit tests covering all patterns

Modified files:
- ResolvedSuggestion.kt: Added Command type for slash commands
- SuggestionsProcessor.kt: /pay shows as autocomplete suggestion
- MarkdownTextEditorState.kt: Command insertion in text editor
- MessageComposerPresenter.kt: Command handling in InsertSuggestion

Note: MessageComposerPresenter sendMessage interception deferred to
Task 6 (requires PaymentFlowPresenter for navigation).
2026-03-27 10:38:46 -07:00
Benoit Marty
7d28c52242 Cleanup 2026-03-25 16:51:41 +01:00
Benoit Marty
747f588fa7 Update UI of replies. 2026-03-25 15:27:36 +01:00
ganfra
92920b862b
Merge pull request #6342 from element-hq/feature/fga/live_location_sharing_setup
Setup live location sharing feature
2026-03-24 15:46:45 +01:00
Benoit Marty
75a6eb21ca
Merge pull request #6453 from element-hq/feature/bma/increaseIconSize
Increase icon size of audio and files in the timeline
2026-03-24 11:59:17 +01:00
renovate[bot]
2f99806603
fix(deps): update dependency androidx.compose.material3:material3 to v1.5.0-alpha15 (#6306)
* fix(deps): update dependency androidx.compose.material3:material3 to v1.5.0-alpha15

* Fix deprecations

* Add bottom sheet workaround

* Fix new lint issues

* Fix and ignore broken tests

* Update screenshots

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
Co-authored-by: ElementBot <android@element.io>
2026-03-24 11:24:07 +01:00
Benoit Marty
67f059a429 Attachments: change icon size to 24 and container to 36 2026-03-24 11:01:10 +01:00
ganfra
9a984e1423 Merge branch 'develop' into feature/fga/live_location_sharing_setup 2026-03-24 10:17:24 +01:00
ElementBot
7179ca867c
Sync Strings (#6435)
* Sync Strings from Localazy

* Sync strings.

---------

Co-authored-by: bmarty <3940906+bmarty@users.noreply.github.com>
Co-authored-by: Benoit Marty <benoit@matrix.org>
2026-03-23 18:05:26 +00:00
Jorge Martin Espinosa
eb7d65263a
Fix long messages not being clickable (#6356)
* Fix long messages not being clickable

As @bmarty found out, `clip = true` causes the click event to be ignored in some cases. Since we have the shape we want to draw and we're using a custom `onDraw` modifier anyway to cut-out part of the path, we can just draw everything using the modifier and avoid using `clip = true`.

This seems to fix the issue.

* Fix clipping of images or other items that cover the bubble

* Fix borders being displayed for contents

* Extract the layer drawing logic into `drawInLayer` to simplify the inlined code. Remove redundant code, those changes are now in the `drawInLayer` block

* Workaround for lint issue: it seems like detekt can't properly detect usages in content receivers

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
2026-03-23 18:11:55 +01:00
Benoit Marty
027da263c4
Merge pull request #6322 from element-hq/feature/bma/iterateDesignOnAttachment
Design iteration on file attachment in the timeline
2026-03-23 14:37:54 +01:00
Gianluca Iavicoli
800a9ab972
Fix keyboard not auto-opening when editing a message (#6412)
* fix: auto-open keyboard when editing a message

* fix: show keyboard on focused editor view instead of root view
2026-03-23 10:54:59 +01:00
bxdxnn
139d75d1ba
Fix room member not tappable in a Thread (#6416) 2026-03-19 14:23:10 +01:00
Benoit Marty
13578aa09b Sync string again. 2026-03-16 14:54:06 +01:00
bmarty
299d5a9394 Sync Strings from Localazy 2026-03-16 00:42:32 +00:00
ganfra
4a29fe4d94 Remove duplicate location content and reorder Live mode 2026-03-13 15:50:33 +01:00
ganfra
ccc5945e6f Fix quality! 2026-03-12 21:12:52 +01:00
ganfra
96147967ac Code cleanup 2026-03-12 12:35:46 +01:00
Benoit Marty
6a646550c8 Improve preview by adding a background color. 2026-03-11 15:43:15 +01:00
Benoit Marty
f97c61a386 Iterate on file attachment rendering in the timeline. Closes #6319 2026-03-11 15:30:15 +01:00
ganfra
0056a3f163 Fix compilation 2026-03-09 21:19:57 +01:00
ganfra
f2d4ffc5bd Introduce LiveLocationContent for the timeline (needs sdk) 2026-03-09 20:54:01 +01:00
ganfra
ffad69b7b9 Make sure we can display both Live and Static locations in ShowLocation 2026-03-09 20:54:01 +01:00
ganfra
8a12cba923 Rename send location to share location 2026-03-09 20:54:01 +01:00
Valere Fedronic
95049849cc
Merge branch 'develop' into valere/rtc/voice_call 2026-03-09 17:18:55 +01:00
ElementBot
73961b4940
Sync Strings (#6302)
Co-authored-by: bmarty <3940906+bmarty@users.noreply.github.com>
2026-03-09 10:38:07 +01:00
Valere
bad6085fb2 review: consistency use isAudioCall everywhere (instead of voiceOnly) 2026-03-06 12:19:05 +01:00
Valere
4406b50542 review: fix bad usage of modifier 2026-03-06 12:15:20 +01:00
Valere
7897101009 fix test for voice call button 2026-03-05 10:09:10 +01:00
Valere
fdd39fa17b on show voice call only option in DMs 2026-03-04 15:08:24 +01:00
Valere
0e3722e52e Merge branch 'develop' into valere/rtc/voice_call 2026-03-04 13:46:54 +01:00
Valere
be370911d2 rename voiceIntent to isAudioCall 2026-03-04 11:10:40 +01:00
Benoit Marty
df6ffd0c57
Sync compound tokens https://github.com/element-hq/compound-design-tokens/releases/tag/v6.10.1 (#6273)
* Import compound token v6.10.1

./tools/compound/import_tokens.sh -b v6.10.1

* Use stop icon from Compound.

* Fix compilation issue.

* Use gradient color in ComposerAlertMolecule. Fixes #6192

* Update screenshots

* Remove ComposerAlertLevel.Default (not in the design).

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
2026-03-03 14:42:27 +01:00
Benoit Marty
b65b9eeab9
Merge pull request #6035 from element-hq/fix/remove-fragment-part-in-mxc-urls
Add `MediaSource.safeUrl` for removing invalid fragment part from URLs
2026-03-03 11:57:49 +01:00
Valere
5491040ac5 WIP: Support using Element Call for voice calls in DMs 2026-03-03 11:50:22 +01:00
ElementBot
cf479a8df0
Sync Strings from Localazy (#6269)
Co-authored-by: bmarty <3940906+bmarty@users.noreply.github.com>
2026-03-02 14:54:50 +01:00
Benoit Marty
de9987deea Use gradient color in ComposerAlertMolecule. Fixes #6192 2026-03-02 13:03:47 +01:00
Jorge Martín
5fb9dcb0da Apply suggestion:
- Added `MediaSource.safeUrl` property replacing `withCleanUrl` method.
- Made `url` private so it can't be used externally.
- Reverted code in `CoilMediaFetcher`
- Also add tests
2026-02-27 09:52:17 +01:00
Benoit Marty
1a99057b31
Merge pull request #6194 from vmfunc/feature/audio-focus-voice-recording
request audio focus when recording voice messages
2026-02-23 13:35:57 +01:00
vmfunc
0cbe326db9 finish recording gracefully when audio focus is lost
if something else grabs focus mid-recording (phone call, etc), stop
the recording and keep the partial result in preview state instead
of silently recording garbage

Signed-off-by: vmfunc <celeste@linux.com>
2026-02-12 18:39:40 +01:00
vmfunc
1412dd789e add RecordVoiceMessage audio focus requester for recording
separates recording from playback focus - willPausedWhenDucked is false
for recording so notification sounds don't interrupt mid-recording

Signed-off-by: vmfunc <celeste@linux.com>
2026-02-12 18:39:39 +01:00
vmfunc
84bfd7712a request audio focus when recording voice messages
Signed-off-by: vmfunc <celeste@linux.com>
2026-02-12 16:28:37 +01:00
Benoit Marty
0bb1a2f801 Fix warning 2026-02-12 14:28:28 +01:00
Benoit Marty
500cc0828b
Merge pull request #6048 from element-hq/renovate/app.cash.paparazzi-2.x
chore(deps): update plugin paparazzi to v2.0.0-alpha04
2026-02-10 16:42:54 +01:00
Jorge Martin Espinosa
6184a63ecc
Ensure aspect ratio of images in the timeline is restricted (#6168)
* Ensure aspect ratio of images in the timeline is restricted

Otherwise, this could cause a crash in Compose since the width and height values could become way too large.
2026-02-10 14:38:55 +00:00