Commit Graph

1325 Commits

Author SHA1 Message Date
another-simple-pixel 753b366b08 Appearance: fix Transparency truncation and SettingsActionItem horizontal padding
Two layout regressions from earlier facelift commits where slider/item
math assumed DEFAULT_PADDING (20dp) for inner card padding, but the
facelift uses CARD_PADDING (16dp outer) + CARD_ITEM_PADDING (15dp inner)
= 31dp per side instead of 20dp.

- Slider widthIn calc in AppToolbarsSection and MessageShapeSection
  used (maxWidth - DEFAULT_PADDING * 2) so the slider was ~22dp wider
  than it should be, shrinking the label Box (weight 1f) and clipping
  "Transparency" to "Transparenc". Switched to
  (CARD_PADDING + CARD_ITEM_PADDING) * 2.
- SettingsActionItemWithContent explicitly passed
  PaddingValues(horizontal = DEFAULT_PADDING) to its SectionItemView,
  overriding the new CARD_ITEM_PADDING default. That made any row using
  SettingsPreferenceItem/SettingsActionItem sit 5dp further inset than
  rows using plain SectionItemViewWithoutMinPadding — visible as a left
  indent on "Tail" relative to "Corner". Replaced with CARD_ITEM_PADDING
  so it matches.

Removed `private` from CARD_PADDING and CARD_ITEM_PADDING in Section.kt
to allow imports from other files (used the same way as SectionView etc.
are imported individually).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:09:18 -07:00
another-simple-pixel 1d978fb2e0 NetworkAndServers: move ConditionsButton into operators card; wrap Save servers in its own card
- "Review conditions" (ConditionsButton — a bare SectionItemView) was
  rendered between the operators card and the messages card on the
  canvas without card chrome. Move it inside the operators SectionView
  lambda after the operator rows, so it shares the card and gets a
  2dp auto-divider above it separating it from the operator list.
- "Save servers" (a bare SectionItemView further down) is now wrapped
  in its own SectionView so it reads as a single-item card matching
  the iOS-style facelift of the rest of the screen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:03:52 -07:00
another-simple-pixel 20daf4b4eb ProtocolServerView: pad CustomServer address field inside its card
The TextEditor (144dp tall input) sat flush against the top and bottom
edges of its containing SectionView card on the New server screen.
Pass padding = PaddingValues(vertical = DEFAULT_PADDING_HALF) to the
SectionView so the field gets 10dp of breathing room top and bottom
inside the card.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:01:41 -07:00
another-simple-pixel a5b1996605 Section: bump hover ripple alpha to 0.08 on LIGHT theme for visibility against canvas
Default Compose Material 1 RippleTheme uses hoveredAlpha=0.04 for LIGHT,
producing a Black·0.04 overlay (~#F5F5F5) on white cards — visually 3
units per channel away from the off-white canvas (~#F2F2F2), so the
hover state blends into the canvas and the row looks unfocused.

Add a section-local SectionRippleTheme that mirrors Material's defaults
for everything except hoveredAlpha on LIGHT (raised to 0.08 → ~#EBEBEB
overlay, ~7 units delta from canvas — visibly distinct). Dark themes
keep Material defaults since their hover contrast is already adequate.

Provided via CompositionLocalProvider in all three SectionView variants
alongside LocalInSectionCard, so it scopes only to section card items.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 08:58:58 -07:00
another-simple-pixel 3e3d092ee9 Section: fix item divider position — paint via drawWithContent at full row bottom
8050676b moved sectionItemDivider() AFTER clickable.padding() in the
modifier chain to make the line paint on top of clickable's hover
indication. Side effect: drawBehind then saw the size of the
padding-reduced content area, not the full row, so dividers rendered
15dp ABOVE the actual row bottom (in the middle of the row's bottom
padding zone) instead of at the row edge between adjacent items.

Fix: keep sectionItemDivider() in the modifier val BEFORE clickable/
padding (so size = full row outer bounds) AND switch from drawBehind
to drawWithContent { drawContent(); drawLine(...) } so the line is
painted AFTER the chain's content + hover indication draw. Both
goals satisfied: divider sits at the true row bottom AND paints on
top of hover overlay.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 08:48:56 -07:00
another-simple-pixel a6bb45fb8d Appearance: add missing SectionDivider import
f922d8fc introduced SectionDivider() call in the themes card but forgot
to add the per-symbol import. SectionView/SectionDividerSpaced etc. in
this codebase are imported individually (Section.kt declares them at
top level, not inside a package), so SectionDivider needs its own
import line.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 08:41:33 -07:00
another-simple-pixel 9d94fa2048 ServersSummaryView: wrap Message reception sections in SectionView card
SubscriptionsSectionView and SMPSubscriptionsSection both rendered their
InfoRows + control item in a plain Column without card chrome — so on
the Servers info screen the "Message reception" section title sat above
loose rows on the gray canvas (no card), inconsistent with the rest of
the screen. Wrap the inner Column in SectionView so the rows get the
raised iOS-style card look. The custom header Row (title + subscription
status indicator) stays outside the card so the icon stays inline with
the title text.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 08:30:38 -07:00
another-simple-pixel c7a6a281c9 ChatInfoView: move E2E encryption card spacer out of SectionView lambda
Same pre-card-chrome pattern: SectionDividerSpaced was inside the
single-row SectionView around the InfoRow, so after PR #6777 added
card chrome it rendered as a white gap inside the card (under the
auto-divider on the InfoRow), producing the "extra divider + gap"
the user reported.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 08:27:47 -07:00
another-simple-pixel fa29bb7a71 GroupChatInfoView: render group members inside the same SectionView card as owner
Previously the members card showed only the current user (owner) and the
add-members button — the actual group members were rendered as separate
LazyColumn items() OUTSIDE the SectionView, so they sat on the gray
canvas without card chrome. Visually inconsistent: owner in a card,
everyone else floating.

Move filteredMembers.value.forEach { ... } INSIDE the SectionView lambda
so every member row is part of the same card as the owner. Drop the
explicit Divider() call (auto-divider handles it now). Move remember
key to member.groupMemberId so per-member state survives reorders.

Trade-off: lazy rendering of member rows is replaced with eager
composition inside a Column. For typical groups (<100 members) this is
imperceptible; very large groups may compose slower on open. Watching
for reports.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 08:26:42 -07:00
another-simple-pixel 75006897e3 ChatWallpaperEditor: wrap loose params in SectionView cards
In ChatInfo > Chat theme screen the wallpaper preset selector, the
wallpaper setup controls, the reset/set-default buttons and the
"Apply to" mode dropdown were rendered as loose composables on a gray
canvas — no card chrome, inconsistent with the rest of Appearance.

Wrap them in SectionView so they read as raised iOS-style cards:
- wallpaper preset selector + setup view → one card
- reset-to-global + set-default buttons → one card
- (advanced mode) Apply-to dropdown → one card
- (collapsed mode) Advanced-settings button → one card

CustomizeThemeColorsSection and ImportExportThemeSection were already
SectionView-wrapped and remain unchanged. UserWallpaperEditor (sister
function with similar layout, lines 28-220) is intentionally left
alone — user reported only the chat-theme entry point.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 08:23:22 -07:00
another-simple-pixel b1a1dad88e ChatInfoView: move chat-ttl footer caption out of SectionView lambda
Same pre-card-chrome pattern: SectionTextFooter("Delete chat messages
from your device.") was inside the ChatTTLOption SectionView lambda, so
after PR #6777 added card chrome it rendered inside the card. Move it
out so the caption sits below the card iOS-style.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 08:11:58 -07:00
another-simple-pixel b186b5b012 DeveloperView: move card footer/bottom-spacer out of SectionView lambdas
Same pre-card-chrome pattern as NetworkAndServers: SectionTextFooter
("Show: Database IDs and Transport isolation...") and SectionBottomSpacer
were inside SectionView lambdas, so after PR #6777 added card chrome they
rendered inside the white card area — the footer caption sat inside the
first card and the 48dp bottom spacer appeared as an empty row at the
end of the deprecated-options card (after SimpleX links).

Move both out of the SectionView lambda so the footer reads as a caption
below the first card and the bottom spacer adds safe-area room after the
deprecated-options card (not inside it).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 08:10:26 -07:00
another-simple-pixel 26e95789be NetworkAndServers: move messages card footer/spacer out of SectionView
Before PR #6777 SectionView had no card chrome, so SectionTextFooter and
SectionDividerSpaced placed inside its content lambda rendered as plain
inline content. After the card chrome was added, the same code rendered
the footer caption and the spacer INSIDE the white card area, producing
an unwanted gap (and visible auto-divider tail) under Advanced network
settings.

Move both out of the SectionView lambda so the footer reads as a caption
below the card (iOS-style) and the spacer separates this card from the
next one.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 08:06:14 -07:00
another-simple-pixel 978f9a458f Appearance: symmetric vertical padding around profile avatar row
ProfileImageSection's Row had Modifier.padding(top = 10.dp), giving 10dp
above the avatar and 0dp below — visibly asymmetric inside the card.
Changed to vertical = 10.dp so top and bottom padding match.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 08:00:22 -07:00
another-simple-pixel f922d8fcd6 Section: repurpose SectionDivider() as explicit 2dp canvas-color line; use in Appearance themes card
SectionDivider() composable had 0 callsites and used Material Divider
with horizontal inset (unused legacy). Repurposed to draw a 2dp
canvas-color Box matching the auto-divider style used by
SectionItemView, gated by LocalInSectionCard so it no-ops outside a
section card.

Use it in Appearance themes card between WallpaperPresetSelector
(custom composable, not a SectionItemView, so no auto-divider) and the
following content (Remove image / Color mode / Dark mode), providing
the visual separator the user expects between the theme grid and the
rows below it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 07:59:30 -07:00
another-simple-pixel 10125572f2 Appearance: drop redundant 10dp spacer between Apply-to row and wallpaper preview
Before section facelift the spacer separated the Apply-to row from the
wallpaper preview block visually. With the new 2dp item divider drawing
under the Apply-to row that separation is already provided, and the spacer
leaves an awkward white gap between the divider and the preview.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 07:56:28 -07:00
another-simple-pixel 92fb07ca68 Section: trim section item horizontal padding to 15dp
CARD_PADDING (16dp) still drives outer card margin from screen edge.
Item content inside the card now uses CARD_ITEM_PADDING = CARD_PADDING - 1.dp,
giving the row text a slightly tighter horizontal inset that reads
better at the current card width.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 07:52:40 -07:00
another-simple-pixel 8050676bb7 Section: paint item divider on top of clickable's hover indication
Previously sectionItemDivider() was inside the modifier val before
clickable, so the hover background drew over it inconsistently — on
hover the row's content area got a tinted overlay while the 2dp
divider area stayed at canvas color, creating visible contrast that
read as a "dark line below hovered row".

Moving the modifier to the end of the chain (after clickable+padding)
makes drawBehind paint after the hover indication, so the divider
color is consistently #F2F2F2-ish regardless of hover state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 07:43:17 -07:00
another-simple-pixel aeb48d522e Section facelift: LIGHT canvas swap, equal padding, 2dp item dividers
- LIGHT canvas (themedBackground) now paints the off-white formula
  (bg.mixWith(onBackground, 0.95f)) so white cards read as raised.
  DARK/BLACK keep palette bg (cards already raised via founder's
  formula in Section.kt). SIMPLEX keeps its gradient.
- Section cards in LIGHT switch from formula to pure white via
  Color.White. DARK/BLACK keep the formula, unchanged.
- Section card horizontal padding equalized to 16dp on outer + inner
  for clean canvas-edge alignment. extraPadding (icon-indented rows)
  keeps DEFAULT_PADDING * 1.7f.
- 2dp dividers between rows inside section cards, color matches the
  per-theme canvas (SIMPLEX uses gradient bottom stop). Implemented via
  Modifier.drawBehind on each SectionItemView, gated by a private
  LocalInSectionCard CompositionLocal set true only by SectionView's
  inner Column — standalone SectionItemView usage (alerts, pickers)
  stays unaffected. Single canvas helper canvasColorForCurrentTheme()
  in Theme.kt is the source of truth for both canvas paint and divider
  color.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 07:25:29 -07:00
Evgeny @ SimpleX Chat 54f890ad88 Merge branch 'master' into ep/new-design 2026-05-15 09:17:42 +00:00
SimpleX Chat 1491f68cd2 6.5.2: android 349, desktop 143 2026-05-14 16:57:01 +01:00
Narasimha-sc c82bf05293 android, desktop: hide private notes from share channel picker; hide share via chat on plain groups (#6958)
* ui: hide saved messages from share channel picker; hide share via chat on plain groups

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* plans: justify share channel link picker filter and group-link button gate

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 16:43:06 +01:00
Evgeny 7497b90e7c core, ui: allow indefinite deletion from history for public channel/group owners/moderators (#6972)
* Revert "core: forward compatible support for owners/admins/moderations deleting channel and public group messages without limitations (#6962)"

This reverts commit 08108ebabb.

* core, ui: allow indefinite deletion from history for public channel/group owners/moderators

* style

Co-authored-by: Evgeny <evgeny@poberezkin.com>

* refactor

* show error on deletion

* better alerts

* test

* plan

* simplify test

* bot api docs

* refactor

* test that removed from history is not delivered to the new subscribers

* fix, refactor

* fix

* rename

* rename predicate in UI

* rename

* do not forward channel deletions from history

* remove redundant check

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-05-13 15:24:52 +01:00
sh 334a50dda5 desktop: add tray support (#6970)
* plans: design and implementation plan for desktop tray icon

Adds a system tray icon to the SimpleX desktop app with first-close
dialog and an Appearance toggle. Covered: minimize-to-tray on Linux,
Windows, and macOS via ComposeNativeTray; tri-state CloseBehavior
preference; unread-dot icon swap; show/quit menu.

The design plan covers the user-facing behavior, library choice
rationale (AWT/Compose Tray is broken on stock GNOME per JDK-8322750;
ComposeNativeTray uses platform-native APIs and is maintained), and
out-of-scope items. The implementation plan splits the work into 8
incremental commits, each leaving the build green.

* desktop: add CloseBehavior preference

* plans: switch tray to built-in Compose Tray with GNOME probe

* desktop: branch close handler on CloseBehavior preference

* desktop: first-close dialog for tray choice

* desktop: tray icon assets and menu strings

* desktop: system tray icon with show/quit menu

* desktop: unread indicator on tray icon

* desktop: Appearance toggle for minimize-to-tray

* desktop: tray feature fixes from audit

- Scope closedByError per application iteration; set before dispatchEvent.
- Short-circuit Ask to Quit when tray is unavailable.
- Sum users.unreadCount (pre-aggregated) instead of iterating chats.
- Replace dialog's captured lambdas with a top-level flag and
  ApplicationScope extension; wrap in SimpleXTheme.
- Probe SystemTray with real add/remove off the EDT.
- Drop duplicate ic_simplex_tray.svg; nudge unread dot to cy=34 to
  stop the r=6 circle clipping at the viewBox bottom.
- Use mkSafeEnumPreference, PreferenceToggle, SectionTextFooter.

* plans: sync desktop tray plans with implementation

* desktop: render close-behavior popup via AlertManager

Replaces the bespoke DialogWindow with AlertManager.shared.showAlertDialogButtonsColumn —
same in-app surface as e.g. the link-previews opt-in alert. Drops isAskingCloseBehavior,
the CloseBehaviorDialog Composable, the resetAskCloseBehavior helper, and the per-iteration
reset call: the alert's lifecycle is now bounded by AlertManager's single slot, so a crash
mid-dialog gets cleanly overwritten by the crash report.

* desktop: reset closeBehavior with 'Reset all hints'

Generalises AppPreferences.hintPreferences to a heterogeneous List<HintPref>
so non-Boolean prefs can participate. Adds closeBehavior to the list, so
'Reset all hints' brings the first-close dialog back.

* desktop: skip muted profiles in tray unread sum

Active profile still counts so the user can see their own unread; non-active
muted profiles contribute zero.

* desktop: dark-theme tray icons

Adds ic_simplex_tray_light and ic_simplex_tray_dot_light — copies of the
existing tray SVGs with the navy back-X swapped to white. Picks the variant
via isInDarkTheme() so the icon stays visible against dark tray backgrounds.
2026-05-13 08:58:42 +01:00
Narasimha-sc 1f25cec949 android, desktop: constrain image height in layout (#6959)
* android, desktop: constrain image height in layout

Clamp the image preview Box's aspect ratio so it never goes
below 1/2.33 (matching the height cap already enforced by
PriorityLayout). Prevents tall image previews from overflowing
into the caption area below.

Analogous to iOS #6732.

* plans: justify image text overlap fix
2026-05-12 16:48:25 +01:00
Narasimha-sc 5d597faf7e desktop: pick a free port for the call server if 50395 is in use (#6963)
* desktop: pick a free port for the call server if 50395 is in use

startServer() bound a hard-coded port (50395); when it was already in use,
NanoWSD threw "BindException: Address already in use: bind" and the call
failed. It now falls back to an OS-assigned free port, and WebRTCController
opens the browser at the actually-bound port (server.listeningPort) -- still
50395 in the normal case, so browser camera/mic permission stays put.

* plans: justify call server port-bind fix
2026-05-12 10:12:39 +01:00
Narasimha-sc e10cfd02e9 desktop: keep text selection on the originally selected message when a new message arrives (#6955)
* desktop: keep text selection on the originally selected message when a new message arrives or is sent

Selection stored positional indices into the merged-items list. When a new
message was appended, the reversed list shifted every index by one — but the
stored start/end indices did not — so the highlight slid onto neighboring
messages.

Anchor the selection to ChatItem IDs instead of list positions. Offsets are
already content-relative (character cursors in rendered text), so they stay
valid across list mutations. Positional indices are derived on read via
derivedStateOf, which keeps per-item reads O(1) amortized. If either
anchored item is removed from the list, a SideEffect synchronously clears
the selection so the copy button does not flash at a stale location.

* desktop: minimize selection fix — anchor ids in SelectionRange

Replaces the previous derivedStateOf-based approach with a surgical
diff: SelectionRange carries startItemId/endItemId alongside the
existing positional indices, and a SideEffect calls resyncIndices()
to translate ids back to current positions when the items list mutates.

All existing call sites of range.startIndex / range.endIndex remain
unchanged. Net diff vs master is +19/-2.

* plans: justify desktop text selection id-anchored fix
2026-05-08 13:55:58 +01:00
Narasimha-sc da9b69ca0b android, desktop: open correct image in fullscreen viewer (#6869)
* android, desktop: open correct image in fullscreen viewer

Fullscreen image viewer occasionally opened a different image than
the one clicked. Root cause: when the LaunchedEffect probe at
ImageFullScreenView.kt:48-55 calls getMedia(initialIndex - 1) to check
whether a previous media item exists, getMedia returns null for both
"no item" and "item found but failed to load" (e.g. undecodable bytes,
missing file, crypto error). The probe treated null as "no previous
item" and called scrollToStart(), which rewrote initialChatId to the
chat's oldest media item - making the viewer display that oldest item
instead of the clicked one.

Fix: scrollToStart() no longer rewrites initialChatId. The pager is
still repositioned to page 0; getMedia(0) resolves against the
already-set initialChatId (the clicked item) and renders it correctly.

* android, desktop: regression test for fullscreen viewer anchor preservation

Drives the public providerForGallery interface: moves the anchor away from
cItemId via currentPageChanged, calls scrollToStart, then reads the anchor
back through onDismiss's scrollTo callback. The pre-fix code rewrote
initialChatId to the chat's oldest showable, which would surface as
scrollTo(2); the fix preserves the anchor and produces scrollTo(1).

* plan: design doc for fullscreen viewer wrong-image fix

Documents the pager state model, the root cause of the wrong-image bug,
why the one-line deletion in scrollToStart fixes it for both call sites,
and why the wider getMedia null-overload refactor is deliberately out of
scope for this fix.
2026-05-08 12:18:45 +01:00
Narasimha-sc 4d43f2d41c desktop: fix copying selected text in reports (#6863)
* desktop: fix copying selected text in reports

Text selection in report items rendered a red reason prefix (e.g. "Spam: ")
before the user's comment but dropped the prefix when copying, because
selection offsets are in rendered-text space while copy extraction was
operating on ci.text / ci.formattedText directly.

Introduce itemPrefixText(ci) as the single source of truth for the rendered
prefix, and drive both selection copy and snap-to-segment from a unified
itemDisplaySegments list that prepends the prefix as a leading segment.
This also fixes mention/link snapping on the selection boundary inside
report comments.

* desktop: scope report-selection fix to report items

Inline a prefix preamble + offset shift in selectedItemCopiedText and
snapOffset instead of routing every item through itemDisplaySegments.
Non-report items now run the original pre-PR loop unchanged; reports
emit the selected slice of the rendered prefix and shift body offsets
by prefix.length.

* desktop: simplify report selection arithmetic

Selection offsets are in display-text space, which already includes the
leading itemPrefixText for reports. Treat the prefix as the leading
display segment and seed displayOffset with prefix.length, instead of
shifting body offsets by prefix.length in the inner loop and gating
snapOffset on offset <= prefix.length.

The inner loop body of selectedItemCopiedText becomes identical to
pre-PR for non-reports (prefix is "" so displayOffset starts at 0),
and snapOffset reduces to a one-line seed change. Same fix, smaller
diff, fewer intermediate variables.

* desktop: drop helper, inline report-prefix in selection only

Revert itemPrefixText helper extraction (TextItemView.kt and
FramedItemView.kt back to pre-PR). Inline the report-prefix expression
at its two use sites in TextSelection.kt directly.

PR diff is now confined to TextSelection.kt: +13/-6.

* desktop: extract itemPrefixText, drop dead defensive code

Re-introduce itemPrefixText(ci) helper in TextItemView.kt and migrate all
four sites that compute the report prefix (FramedItemView,
ChatPreviewView, TextSelection x2). The prefix expression now has one
definition and one place to change.

Also drop the unreachable sel.first.coerceAtLeast(0) on the prefix-slice
append — selectedRange guarantees sel.first >= 0.

* plans: justify desktop fix for copying selected text in reports

Add 2026-05-08-fix-select-in-reports.md covering the problem, the offset
flow, the minimal structural change (seed displayOffset with prefix.length),
the itemPrefixText single-source-of-truth migration across the four
prefix sites, the verified edge-case table, and the rollback path.
2026-05-08 12:15:52 +01:00
Narasimha-sc 8c9c6471a7 desktop: fix RTL text rendering under the send button (#6906)
* desktop: fix RTL text rendering under the send button (#4137)

The chat composer's text field reserved 50dp on the wrong horizontal side
when an RTL message was typed under an LTR system locale: BiDi auto-detection
right-aligned the text onto the BottomEnd edge where the send button sits,
hiding the first characters as they were typed.

The padding was originally written inside the CompositionLocalProvider(
LocalLayoutDirection provides Rtl) scope (#4675), where start resolved to
the right edge for RTL paragraphs. The "edge to edge design" refactor
(#5051) lifted the modifier out of that scope onto the outer BasicTextField,
so start began resolving against the global LTR direction and the
reservation drifted to the left.

Always reserve on the global end - the same side Alignment.BottomEnd in
SendMsgView resolves to - so the reservation tracks the send button
regardless of locale or typed-text direction. Behavior is byte-identical
for LTR text and for any RTL-locale combination; only the buggy
"RTL text + LTR system locale" pair changes.

* desktop: minimise diff of RTL fix to 2 lines (#4137)

The previous commit (bfc111cc6) renamed/removed several helper locals
and rewrote the comment block alongside the behaviour change. The
behaviour-changing part is just two lines: making startPadding always
0.dp and endPadding equal to startEndPadding.

Restore the surrounding code (startEndPadding name, startPadding decl,
PaddingValues argument, .padding modifier, and the original two-line
comment) to its master form so the PR's only effect on master is the
two-line fix.

Behaviour: cases 1, 3, 4 of the locale x text matrix are byte-identical
to master. Only case 2 (LTR locale + RTL text) flips the reservation
from the wrong side to the correct side.

* plans: desktop RTL composer fix (#4137)

* plans: align with surgical 2-line fix in PR (#4137)
2026-05-08 11:10:14 +01:00
spaced4ndy d986c00530 ui: disable relay management (#6951) 2026-05-08 08:37:55 +00:00
spaced4ndy 6f8a07e4ea core, ui: relay management - add, remove relays, synchronization to relay list (#6917) 2026-05-08 07:19:16 +00:00
spaced4ndy d9cfc9bd3d ui: adjust create channel ui (#6950) 2026-05-08 06:27:26 +00:00
Evgeny Poberezkin 79d21f06bf 6.5.1: android 347, desktop 142 2026-05-02 20:30:43 +01:00
spaced4ndy ce0e9c37c1 ui: improve channel creation ux (#6933)
* ui: improve channel creation ux

* update

* update

* update

* wip

* update
2026-05-01 20:42:15 +01:00
Evgeny Poberezkin d6c9c0ee47 6.5: android 345, desktop 140 2026-04-30 10:13:29 +01:00
Evgeny ab2d036301 android, desktop: reduce timeout and do not use hardward acceleration for video preview generation (#6924)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-04-30 08:37:54 +01:00
Evgeny abcce61f32 ui: translations (#6921)
* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2768 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/hu/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2392 of 2392 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/es/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2392 of 2392 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/hu/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2768 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* Translated using Weblate (German)

Currently translated at 100.0% (2768 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/de/

* Translated using Weblate (German)

Currently translated at 100.0% (2392 of 2392 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/de/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2768 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/hu/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2392 of 2392 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/es/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2392 of 2392 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/hu/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2768 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* Translated using Weblate (German)

Currently translated at 100.0% (2768 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/de/

* Translated using Weblate (German)

Currently translated at 100.0% (2392 of 2392 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/de/

* Translated using Weblate (German)

Currently translated at 100.0% (2768 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/de/

* Translated using Weblate (Spanish)

Currently translated at 99.9% (2767 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (2768 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/zh_Hans/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2392 of 2392 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/hu/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2768 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/hu/

* Translated using Weblate (Russian)

Currently translated at 100.0% (2392 of 2392 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/ru/

* Translated using Weblate (Italian)

Currently translated at 100.0% (2392 of 2392 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/it/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2768 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/hu/

* Translated using Weblate (Italian)

Currently translated at 100.0% (2768 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/it/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2392 of 2392 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/hu/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2768 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2392 of 2392 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/es/

* Translated using Weblate (Russian)

Currently translated at 100.0% (2768 of 2768 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/ru/

* process localizations

* ru corrections

Co-authored-by: Evgeny <evgeny@poberezkin.com>

---------

Co-authored-by: summoner001 <summoner@disroot.org>
Co-authored-by: No name <usir.alerts@onionmail.org>
Co-authored-by: mlanp <github@lang.xyz>
Co-authored-by: 大王叫我来巡山 <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
2026-04-29 23:23:13 +01:00
Narasimha-sc 7ea3db7b3c ui: fix crash opening About SimpleX Chat (#6902)
* ui: fix crash and logo cutoff on About SimpleX Chat

OnboardingShrinkingLayout calls .first() on each slot's measurables,
crashing when the button slot is empty. About passes onboardingStage =
null, in which case the button slot emits no children. Have the About
branch emit a 0x0 Spacer so the slot always has one measurable.

Also add a top inset for the SimpleX logo when reached from About in
non-oneHandUI mode — without it the top app bar overlaps the logo.

* style

Co-authored-by: Evgeny <evgeny@poberezkin.com>

* Apply suggestion from @epoberezkin

Co-authored-by: Evgeny <evgeny@poberezkin.com>

---------

Co-authored-by: Evgeny <evgeny@poberezkin.com>
2026-04-29 20:58:01 +01:00
Evgeny Poberezkin 12e208178d 6.5-beta.12: android 344, desktop 139 2026-04-29 16:10:06 +01:00
spaced4ndy c0125e6622 android: fix connect banner card layout (wip) (#6922) 2026-04-29 15:45:42 +01:00
Evgeny aa7f1049b5 android: fix link preview fetch via SOCKS (#6919)
* android: fix link preview fetch via SOCKS

* fix: add timeouts to link preview image fetch

Match the 10s timeout already on the Jsoup HTML fetch. Without these,
a slow or dead SOCKS proxy hangs the image fetch indefinitely, holding
the previewMutex and blocking every subsequent preview.

* timeout

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
Co-authored-by: shum <github.shum@liber.li>
2026-04-29 13:19:23 +01:00
sh 01906ae1b2 android, desktop: support link preview generation with socks (#6907)
* android, desktop: fix link previews bypassing SOCKS proxy

getLinkPreview used Jsoup.connect() and URL.openStream() directly,
bypassing the configured SOCKS proxy. Both the HTML fetch and image
download now route through the proxy when one is configured.

If the proxy address is misconfigured (unparseable port), the preview
is cancelled and the user is alerted rather than falling back to a
direct connection.

When enabling SOCKS proxy with link previews active, or enabling link
previews while SOCKS is active, the user is warned that DNS lookups
may still occur locally and given the option to disable previews.

Updates the SOCKS proxy limitations notice to clarify that calls
cannot be proxied, and highlights it in warning colour.

Note: DNS lookups may still occur locally before the SOCKS connection
is established. Full SOCKS5h hostname forwarding is a separate follow-up.

* android, desktop: fix SOCKS proxy parser, auth credentials, and repeated alert in link previews

- Build proxy from typed NetworkProxy fields instead of parsing socksProxy string, fixing breakage on IPv6 hosts and USERNAME auth configurations
- Register java.net.Authenticator for SOCKS5 credential negotiation (Java 21 SocksSocketImpl uses RequestorType.SERVER for this callback)
- Remove per-keystroke invalid-proxy alert, which fired on every URL change for valid but unparseable proxy strings

* ui: drop link preview SOCKS warnings and strings

* ui: soften link preview alert when SOCKS is on

Show the link previews opt-in alert in both SOCKS-on and SOCKS-off
cases (previously skipped entirely when SOCKS was on). When SOCKS
is on, use a softer description that mentions the proxy and the
remaining local DNS lookup risk, and render the Disable button in
primary colour instead of red.

Also drop the link-previews caveat from the SOCKS limitations
footer since previews now go through the proxy.

* fix: harden socks proxy auth in link previews

- Gate the SOCKS5 Authenticator on host:port match so destination 401
  challenges no longer leak proxy credentials via the JDK auto-retry.
- Snapshot Authenticator.getDefault() and restore in finally to stop
  leaking process-global state.
- Mutex around getLinkPreview to serialize concurrent calls.
- Generate a random UUID per call in ISOLATE mode for stream isolation.
- Skip auth when USERNAME mode has empty username or password.

* ui: shift red emphasis from Disable to Enable in link preview alert

Disable is now always primary; Enable is red by default and primary
when SOCKS is on. The dangerous action is enabling without proxy
protection, not disabling.

* ui: append SOCKS notice to link preview alert

---------

Co-authored-by: iversonianGremling <24989959+iversonianGremling@users.noreply.github.com>
2026-04-29 10:52:38 +01:00
Evgeny 976f5efaf5 ui: translations (#6914)
* Translated using Weblate (Italian)

Currently translated at 98.9% (2736 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/it/

* Translated using Weblate (Hungarian)

Currently translated at 98.4% (2357 of 2393 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/hu/

* Translated using Weblate (Russian)

Currently translated at 95.5% (2642 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/ru/

* Translated using Weblate (Catalan)

Currently translated at 90.3% (2500 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/ca/

* Translated using Weblate (Polish)

Currently translated at 91.2% (2524 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/pl/

* Translated using Weblate (Czech)

Currently translated at 91.3% (2526 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/cs/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 99.6% (2757 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/zh_Hans/

* Translated using Weblate (Romanian)

Currently translated at 89.6% (2481 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/ro/

* Translated using Weblate (Spanish)

Currently translated at 98.0% (2712 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* Translated using Weblate (German)

Currently translated at 98.9% (2736 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/de/

* Translated using Weblate (Hungarian)

Currently translated at 99.4% (2751 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/hu/

* Translated using Weblate (Hungarian)

Currently translated at 99.9% (2392 of 2393 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/hu/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2766 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/hu/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (2766 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/zh_Hans/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2393 of 2393 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/hu/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2766 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/hu/

* Translated using Weblate (Spanish)

Currently translated at 99.0% (2741 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* Translated using Weblate (Spanish)

Currently translated at 97.6% (2337 of 2393 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/es/

* Translated using Weblate (Spanish)

Currently translated at 99.9% (2765 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* Translated using Weblate (Spanish)

Currently translated at 98.2% (2352 of 2393 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2766 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2393 of 2393 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2766 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* Translated using Weblate (Italian)

Currently translated at 100.0% (2393 of 2393 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/it/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2393 of 2393 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/hu/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (2766 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/hu/

* Translated using Weblate (Italian)

Currently translated at 100.0% (2766 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/it/

* Translated using Weblate (German)

Currently translated at 100.0% (2393 of 2393 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/de/

* Translated using Weblate (German)

Currently translated at 100.0% (2766 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/de/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2393 of 2393 strings)

Translation: SimpleX Chat/SimpleX Chat iOS
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/ios/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (2766 of 2766 strings)

Translation: SimpleX Chat/SimpleX Chat Android
Translate-URL: https://hosted.weblate.org/projects/simplex-chat/android/es/

* process localizations

* corrections

* export

---------

Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: summoner001 <summoner@disroot.org>
Co-authored-by: fran secs <fransecs@gmail.com>
Co-authored-by: Wiesław Fijołek <percival@users.noreply.hosted.weblate.org>
Co-authored-by: zenobit <zenobit@disroot.org>
Co-authored-by: 大王叫我来巡山 <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Nicolae Fericitu <cni@disroot.org>
Co-authored-by: No name <usir.alerts@onionmail.org>
Co-authored-by: mlanp <github@lang.xyz>
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-04-29 10:19:03 +01:00
Evgeny 5934569d59 android: onboarding font size (#6915)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-04-29 09:13:29 +01:00
Narasimha-sc b13711ddbc android: fix system navigation bar overlapping call control buttons during call (#6885)
The active-call action button row (mute, speaker, hang up, flip/toggle camera)
was rendered with only a fixed 20.dp bottom padding. Under edge-to-edge layout
on devices with 3-button navigation, the system nav bar (~48.dp) drew on top
of these buttons, hiding part of them.

Add `.navigationBarsPadding()` to the BoxWithConstraints holding the buttons
so the row floats above the system nav bar inset. No effect on devices using
gesture nav (the inset there is small enough to not collide).
2026-04-29 08:05:45 +01:00
Evgeny aac6dfe0d5 ui: android/desktop ru translations (#6897)
* ui: android/desktop ru translations

* align translations

* remove unused translation

* amend translations

* process localizations

* fix formats

* correction

* fix translations

* fixes

* process localizations, fix key

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-04-28 23:22:34 +01:00
spaced4ndy 51480958c4 ui: redesign toolbar position card (#6901) 2026-04-28 14:25:40 +00:00
sh ed3b85e103 desktop: replace copy-assets shell script with gradle task (#6900) 2026-04-28 11:52:06 +01:00
Evgeny Poberezkin ab4b056c60 6.5-beta.11: android 343, desktop 138 2026-04-27 18:44:00 +01:00