Commit Graph

3453 Commits

Author SHA1 Message Date
Evgeny Poberezkin 58201212d0 Merge branch 'master' into ep/new-design 2026-05-18 09:48:54 +01:00
sh c165663555 desktop: prevent duplicate launches (#6979)
* desktop: prevent duplicate launches

Acquires a file lock and listens on a loopback ServerSocket in dataDir.
A second launch signals the running instance to restore its window and
exits silently. See plans/2026-05-13-desktop-single-instance.md.

* desktop: un-minimize window in showWindow

toFront() does not un-minimize a JFrame on any AWT platform. Clear the
ICONIFIED bit so a minimized window restores; preserves MAXIMIZED_BOTH.
Also fixes the same case when restoring from the tray icon.

* desktop: move showWindow from DesktopTray to DesktopApp

It has callers outside the tray (single-instance signal) and belongs
next to simplexWindowState, which it operates on.

* simplify

* refactor

* desktop: start show-file watcher when choosing minimize from first-close dialog

The handleCloseRequest path already starts the watcher when minimizing to
tray; the Ask-dialog path did not, so the first-time user who picks
"Minimize to tray" got a hidden window with no signal handling — a
duplicate launch would not restore it.

* desktop: always watch for duplicate-launch signal, drop hung-instance alert

The watcher now runs for the JVM lifetime once the lock is acquired,
not only when minimized to tray. Duplicate launches always restore the
primary's window (un-minimize, un-tray-hide, toFront) instead of being
silently dropped when the primary is not minimized.

Drops the "may be hung, start anyway?" popup and the two strings — that
fallback was needed only because the watcher could miss signals. With
the always-on watcher there is no scenario where the primary fails to
consume simplex.show, so the escape hatch becomes dead code.

* desktop: alert when primary's watcher doesn't consume the show file

Restores the "another instance may be running" alert. Every duplicate
launch waits up to 1s for the primary's watcher to delete the show file
it just created. If the file is consumed within the window, the
duplicate exits silently. If still there after 1s the primary is hung
and the alert fires.

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-05-18 09:15:20 +01:00
Evgeny @ SimpleX Chat 23b0e41d87 remove diff noise 2026-05-18 08:04:19 +00:00
Evgeny @ SimpleX Chat efb32a8619 Merge branch 'master' into ep/new-design 2026-05-18 07:47:51 +00:00
another-simple-pixel d9d95e018d Chat info / Group info: use full spacing between two title-less cards
ChatInfoView (Contact prefs/Send receipts/Chat theme → Delete messages) and GroupChatInfoView (Member reports → Edit group profile) both used SectionDividerSpaced(maxBottomPadding = false) = 10dp between two cards that have neither header nor footer touching the gap, so the tight variant wasn't justified. Switch to the default 20dp.
2026-05-16 15:21:33 -07:00
another-simple-pixel 29be15404f GroupLink / WelcomeMessage: use SectionDividerSpaced between adjacent cards
Three places had adjacent SectionView cards with no spacer (GroupLinkView QR + actions, WelcomeMessageView non-owner preview + copy), or used a one-off Spacer(8.dp) instead of the conventional helper (owner mode-button card). Replace with SectionDividerSpaced() so all between-card gaps live behind one helper.
2026-05-16 15:13:22 -07:00
another-simple-pixel 2957e4033c ChatInfoView: hide Servers section header when there is no server content
When both chatSubStatus and cStats are null, the SectionView body rendered as empty (zero-height card) but the SERVERS title still appeared, leaving an orphan header between E2E encryption and Clear chat. Gate the whole section on having at least one of the two.
2026-05-16 14:53:24 -07:00
another-simple-pixel 566e6c1934 ChatInfoImage: lighten LIGHT default avatar to halfway between white and canvas 2026-05-16 14:41:58 -07:00
another-simple-pixel 5d1b229708 Section: tighten icon-to-text spacing in TextIconSpaced by 2dp 2026-05-16 14:36:23 -07:00
another-simple-pixel eac067a717 ChatInfoImage: dark themes use secondaryVariant for default avatar to match UserPicker
The mixWith canvas-darkening formula only lands well in LIGHT. For DARK / BLACK / SIMPLEX, fall back to secondaryVariant, which UserPicker already uses for the active profile avatar — keeps placeholder avatars consistent across the app on dark themes.
2026-05-16 14:34:25 -07:00
another-simple-pixel 3f94b53217 Appearance: symmetric vertical padding around Font size and Zoom preview tiles
Both rows used Modifier.padding(top = 10.dp) so the tile hugged the bottom of the SectionView card. Switch to padding(vertical = 10.dp) to match the symmetric padding used by ProfileImageSection.
2026-05-16 14:33:09 -07:00
another-simple-pixel 0b8be6db00 ChatInfoImage: place default avatar one canvas-shade darker than the canvas
secondary (#8B8786) was too dark. Use background mixed with onBackground at 0.88 — same darkening recipe as canvasColorForCurrentTheme uses with 0.94, applied a step further. On LIGHT this lands near #E1E1E1: 15 units darker than the canvas, matching how the canvas sits 15 darker than white.
2026-05-16 14:29:50 -07:00
another-simple-pixel 32ddd09c8f UserPicker: align item padding with Settings, add divider after inactive-users grid
UserPickerOptionRow no longer applies extraPadding on desktop, and the Settings row uses default SectionItemView padding instead of its own. Both now match the CARD_ITEM_PADDING used in Settings screens. After the inactive-users avatar grid in the unified card, paint a SectionDivider so it visually separates from Your chat profiles.
2026-05-16 14:04:05 -07:00
another-simple-pixel 28f9f1e33d ChatInfoImage: default placeholder icon color to secondary
secondaryVariant is near-white (#F1F2F6) and disappears against the gray canvas. Use the visible secondary tone instead so default avatars without a photo are legible on both card and canvas backgrounds.
2026-05-16 14:03:39 -07:00
another-simple-pixel dd4b64d56a UserPicker: merge SecondSection + GlobalSettings into one card on portrait
Both Android and desktop portrait now show address, preferences, (desktop: inactive-users grid), profiles, link mobile / use from desktop, and settings inside a single SectionView card. Desktop landscape keeps the side-by-side two-card layout.
2026-05-16 13:54:13 -07:00
another-simple-pixel 64ead9720d ChatListNavLinkView.android: fix LocalInSectionCard import path
LocalInSectionCard is declared in Section.kt which has no package (root package), so it must be imported as 'import LocalInSectionCard', not as 'chat.simplex.common.views.helpers.LocalInSectionCard'.
2026-05-16 13:44:57 -07:00
another-simple-pixel 9bcdcbbbcb UserPicker: use canvas color on desktop and split SecondSection around inactive-users grid
Desktop background was MaterialTheme.colors.surface (white) so the SectionView cards introduced earlier were invisible. Switch to canvasColorForCurrentTheme() to match Android.

Drop the explicit Divider above the inactive-users grid: split SecondSection into two SectionView cards with the avatar grid between them so the section dividers come from the cards themselves.
2026-05-16 13:42:48 -07:00
another-simple-pixel f0383b1873 Revert "UserPicker: gate SectionView card wrap on Android only"
This reverts commit be365e55ae.
2026-05-16 13:40:18 -07:00
another-simple-pixel be365e55ae UserPicker: gate SectionView card wrap on Android only
Desktop UserPicker doesn't have a canvas background, so white cards on the white surface were invisible and the existing desktop divider above inactive users looked stray next to the SectionItemView mini-dividers.
2026-05-16 13:39:04 -07:00
another-simple-pixel 3a71182350 UserPicker: wrap menu options in SectionView cards (SecondSection + GlobalSettingsSection) 2026-05-16 13:30:58 -07:00
another-simple-pixel 43855ae07d CreateProfile: add vertical gap between profile fields and Create profile action card 2026-05-16 13:20:14 -07:00
another-simple-pixel c437fc59ee ServersSummaryView: split SMP/XFTP server summary into separate top-level cards
The summary layouts wrapped Stats / Subscriptions / Sessions inside the outer Server address SectionView, which produced nested cards and pushed the Statistics 'Starting from...' footer inside a card. Unnest them so each section is its own card with proper spacing and the footer renders outside.
2026-05-16 13:19:46 -07:00
another-simple-pixel c45768a402 ServersSummaryView: align Message reception header indent with other section headers 2026-05-16 13:18:52 -07:00
another-simple-pixel 4cbfea727f Section: align InfoRow / IndentedInfoRow horizontal padding with CARD_ITEM_PADDING
InfoRow defaulted to DEFAULT_PADDING (20dp), but card chrome adopted CARD_ITEM_PADDING (15dp) for SectionItemView and InfoRowTwoValues. Inside a card, rows of different kinds visibly jumped left/right. Bring InfoRow and its IndentedInfoRow variant onto the same baseline.
2026-05-16 13:18:26 -07:00
another-simple-pixel f2ef38092a GroupLinkView: wrap action items below QR in SectionView card 2026-05-16 13:09:53 -07:00
another-simple-pixel edb3495a8f GroupWelcomeView: wrap message editor/preview and buttons in SectionView cards 2026-05-16 13:04:02 -07:00
another-simple-pixel 9114a36848 Section: bump section item minHeight by 2dp more (56 → 58) 2026-05-16 13:03:11 -07:00
another-simple-pixel 633e0f4140 Section + ChatListNavLink.android: align in-card chat row divider with desktop; canvas to 0.94
Two changes:

1) Theme.kt LIGHT canvas: 0.97f → 0.94f (#F0F0F0). User wants more
   contrast against cards. With Material's default 0.04-alpha hover
   (#F5F5F5) this puts hover LIGHTER than canvas by 5 units — unusual
   direction but it's the user's call; they'll evaluate visually.

2) ChatListNavLinkView.android: when rendered inside a SectionView card
   (e.g. contact list inside NewChatSheet after the forEach-into-card
   refactor), use SectionDivider() — same 2dp full-width canvas-color
   divider as desktop. Outside a card (main chat list), fall back to
   the original Material `Divider(Modifier.padding(horizontal = 8.dp))`
   so unchanged for that context.

3) LocalInSectionCard made `internal` so the android-specific file can
   read it. Same pattern as LocalAppColors etc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 12:48:34 -07:00
another-simple-pixel 64d8fca9cd Migrate views: move all SectionTextFooter / SectionSpacer out of SectionView lambdas
Same pre-card-chrome pattern as elsewhere. MigrateToDevice (4 footers)
and MigrateFromDevice (9 footers + 1 SectionSpacer in error view)
historically wrote captions and inter-card spacers inside their
SectionView content lambdas. After PR #6777 added card chrome these
rendered inside the white cards.

MigrateToDevice fixes (4 footers, one per sub-view):
- Confirm network settings footer
- Database init failed retry footer
- Archive import failed retry footer
- Passphrase entering dynamic footer

MigrateFromDevice fixes (9 footers + 1 SectionSpacer):
- ChatStopFailed view footer
- Passphrase confirmation footer
- Upload confirmation footer
- Upload failed retry footer
- Link shown view: archive-will-be-deleted + choose-migrate footers
- Finished view: 2 warning footers (must-not-use-two-devices,
  using-on-two-devices-breaks-encryption)
- Implicit SectionSpacer at ChatStopFailed view also moved out

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 12:32:15 -07:00
another-simple-pixel e2e3958d67 Move SectionTextFooter / Spacer out of cards in 5 screens
Fixes from the user's verified list of misplaced footers/spacers:

- ChatInfoView: SimpleX address footer ("You can share this address
  with your contacts to let them connect with you.") moved out of the
  address SectionView lambda.
- GroupMemberInfoView: same string for member address.
- Appearance: SectionSpacer in the Image-wallpaper branch (after
  "Remove image" button) removed — it created 30dp empty padding
  inside the THEMES card only when a custom image was selected.
- NotificationsSettingsView: Xiaomi battery-optimization footer
  ("Xiaomi devices: please enable Autostart...") moved out of the
  notifications SectionView lambda (visible only on Xiaomi devices
  in Periodic/Service notification mode).
- ConnectMobileView: dropped the 20dp Spacer that sat inside the QR
  SectionView after the developer-tools "Share link" row — visible
  as extra padding below Share link inside the card.

Same pre-card-chrome pattern as other moves: helpers placed inside
SectionView lambdas before PR #6777 rendered fine when SectionView was
a plain Column; after card chrome they render inside the white card.
Moved them outside so footers read as captions and spacers actually
separate cards.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 12:26:37 -07:00
another-simple-pixel f9b4c97d3f Section: bump section item minHeight by 6dp (50 → 56)
User asked for taller settings rows. Bump the default minHeight in
all four SectionItemView family functions from DEFAULT_MIN_SECTION_ITEM_HEIGHT
(50dp) to DEFAULT_MIN_SECTION_ITEM_HEIGHT + 6.dp (56dp).

Scoped to SectionItemView callers only — does not touch the global
DEFAULT_MIN_SECTION_ITEM_HEIGHT constant, so non-section callers
(ChatItemInfoView, ComposeContextProfilePicker, TagListView,
UserPicker) keep the 50dp baseline.

Callers that pass explicit minHeight (e.g. 54dp in GroupChatInfoView
members) are unaffected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 11:57:33 -07:00
another-simple-pixel 0c6ec43a8d Section + Theme: lighten LIGHT canvas to 0.97; revert custom hover overlay
User feedback: the off-white canvas at 0.95 (#F2F2F2) read as too
dark. Two coordinated changes:

- canvasColorForCurrentTheme LIGHT branch: 0.95f → 0.97f. Canvas now
  #F7F7F7 (3% darker than white, was 5%). Still distinct from pure
  white card but lighter.

- Drop the custom sectionItemHover Modifier helper (and its hoverable
  + InteractionSource + background machinery). The reason for the
  custom hover was that the default Material 0.04-alpha ripple hover
  (#F5F5F5 on white card) blended with the old #F2F2F2 canvas. With
  the lighter canvas at #F7F7F7 the default hover #F5F5F5 is now
  visibly darker than canvas (2 units delta) — visible enough at
  Material default without our custom override.

Removed unused MutableInteractionSource and collectIsHoveredAsState
imports.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 11:54:26 -07:00
another-simple-pixel f75bbf9059 Section: suppress hover on rows whose action is an inline control (switch/dropdown)
sectionItemHover used to show on every row inside a section card. But
rows where the action is an inline control (switch via PreferenceToggle,
dropdown via ExposedDropDownSettingRow) are not "interactive as a row"
— the user has to hit the actual control, not the whole row. Showing
hover on the whole row was misleading.

Add `clickable: Boolean = true` param to sectionItemHover; suppress when
false. SectionItemView and SectionItemViewSpaceBetween pass
`clickable = click != null`. SectionItemViewLongClickable keeps the
default (its click is non-nullable, always interactive).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 11:46:41 -07:00
another-simple-pixel 8862e05b7f SocksProxySettings: split UseOnionHosts so the dynamic description footer renders outside the card
UseOnionHosts wrapped its ExposedDropDownSettingRow and a dynamic
SectionTextFooter ("Onion hosts will be used when available." / similar)
in a Column, so when UseOnionHosts was called inside a SectionView
lambda the footer rendered inside the white card.

Split into two composables:
- UseOnionHosts — only the dropdown row (no longer wraps in Column)
- UseOnionHostsDescription — only the dynamic SectionTextFooter,
  called separately by the caller

Shared `onionHostsValues` is now a private @Composable val accessible
to both. In SocksProxySettings, UseOnionHostsDescription is now placed
AFTER the SectionView block (alongside the existing
"Disable onion hosts when not supported" caption) so the dynamic
description reads as a caption below the card.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 10:12:26 -07:00
another-simple-pixel 54ef065589 SocksProxySettings: move section text footers out of SectionView lambdas
Same pre-card-chrome pattern as elsewhere: two SectionTextFooter calls
("Disable onion hosts when not supported" and the proxy-auth footer)
were inside their SectionView lambdas in SocksProxySettings, so after
the card chrome was added they rendered inside the white cards as
inline content. Move both out so they read as captions below the
corresponding cards.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 10:03:13 -07:00
another-simple-pixel aaff2c8455 NetworkAndServers: rewrite UseSocksProxySwitch via SettingsActionItemWithContent
UseSocksProxySwitch was a custom Row with hard-coded horizontal padding
of DEFAULT_PADDING (20dp) — but its neighbours on the messages card are
SettingsActionItem rows that go through SectionItemView with the new
CARD_ITEM_PADDING (15dp). 5dp icon misalignment between the SOCKS
toggle row and the rest, plus no auto-divider underneath since it
wasn't a SectionItemView.

Replace the custom Row with SettingsActionItemWithContent — same
icon + label + DefaultSwitch shape, now wrapped in SectionItemView so
it shares padding and auto-divider with siblings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 10:02:07 -07:00
another-simple-pixel 5115ac4fe7 RTCServers: wrap Configure ICE servers toggle in SectionView card
Your ICE servers screen had its Configure-ICE toggle and the description
text / editor / read-only display all directly in a raw Column with no
card chrome. Wrap the toggle row in SectionView so it reads as a card
matching the iOS-style facelift. The description text and the
TextEditor / read-only Surface stay in the same loose Column below
(they're a form/display block, not a settings row).

Removed the explicit `padding = PaddingValues()` on the
SectionItemViewSpaceBetween — inside SectionView it inherits
CARD_ITEM_PADDING by default which is what we want now.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:58:57 -07:00
another-simple-pixel dc7f5427fc Section: lighten section item hover overlay from 0.08 to 0.05 alpha
0.08 read as too dark on white cards. Original Compose default 0.04
blended with the off-white canvas (#F2F2F2 vs ~#F5F5F5). 0.05 is the
midpoint — still visibly distinct from canvas (~#F2F2F2 canvas vs
~#F3F3F3 hover on white card) but no longer reads as a heavy box.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:56:52 -07:00
another-simple-pixel 17a6e344f3 Section: suppress sectionItemHover on disabled SectionItemView
sectionItemHover was applied unconditionally inside section cards, so a
disabled row would still show the hover overlay on mouseover —
misleading: the visible interactive feedback contradicts the disabled
state (no click reaction).

Add `enabled: Boolean = true` parameter; the helper now returns `this`
unchanged when `enabled = false`. The 3 SectionItemView family
functions that own a modifier chain pass `enabled = !disabled`.
SectionItemViewWithoutMinPadding inherits through SectionItemView delegation.

Non-clickable info rows (click == null but disabled = false) still get
the hover overlay — that's intentional cursor feedback matching iOS
Settings behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:53:29 -07:00
another-simple-pixel f223267687 Section: replace deprecated RippleTheme override with modern Modifier.hoverable + background
Drop SectionRippleTheme/RippleAlpha/LocalRippleTheme machinery (deprecated
in newer Compose Material, would not compile with the project's warnings-
as-errors policy without DEPRECATION_ERROR suppress, which is a code
smell). Replace with a Modifier.hoverable + Modifier.background pattern —
the modern Compose-native way to apply a hover overlay:

- New private @Composable Modifier.sectionItemHover() that:
  - returns Modifier as-is outside SectionView card (LocalInSectionCard = false)
  - inside a card, attaches its own MutableInteractionSource via .hoverable()
    and paints a transparent or onBackground@0.08-alpha background based on
    collectIsHoveredAsState

- Applied alongside .sectionItemDivider() in each SectionItemView modifier
  chain. Click ripple keeps coming from Modifier.clickable's own indication
  (default ripple, no changes there).

- Drop @file:Suppress deprecation lines; drop SectionRippleTheme object;
  drop ripple imports; drop LocalRippleTheme from CompositionLocalProvider
  calls in three SectionView variants.

Visual result identical to the previous attempt (hovered row gets a visible
gray overlay on LIGHT canvas), no deprecated APIs, no warnings-as-errors
fight. Click ripple unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:46:55 -07:00
another-simple-pixel acf47cbcb4 Section: also suppress DEPRECATION_ERROR — RippleTheme is @Deprecated(level=ERROR)
Previous attempt (4bf981a6b) suppressed DEPRECATION but the Compose
library deprecated RippleTheme with level=DeprecationLevel.ERROR, which
requires the DEPRECATION_ERROR suppression key instead. Add both so
either severity is covered.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:44:16 -07:00
another-simple-pixel 4bf981a6b9 Section: suppress RippleTheme deprecation warnings (build was treating warnings as errors)
`androidx.compose.material.ripple.RippleTheme` and `LocalRippleTheme`
were deprecated in newer Compose Material in favor of the modern
Indication APIs. Our SectionRippleTheme override (a5b199660) hit those
deprecations and the project's Kotlin compiler flags treat warnings as
errors, breaking the build.

Add `@file:Suppress("DEPRECATION")` to Section.kt — narrow file-level
scope. Modern Indication-based ripple migration is a separate, larger
concern; suppress for now so the section hover-alpha override keeps
working.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:40:14 -07:00
another-simple-pixel 8f434477b2 ConnectMobileView: move footer + spacer out of "this device name" SectionView lambda
Same pre-card-chrome pattern: SectionTextFooter and SectionDividerSpaced
were inside the SectionView around DeviceNameField + multicast toggle,
so they rendered inside the white card after PR #6777 — visible as an
extra empty padding below the "Discoverable via local network" toggle
(the SectionDividerSpaced 10dp Spacer inside the card).

Move both outside the SectionView so the footer reads as caption below
the card and the spacer separates this card from the next.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:34:35 -07:00
another-simple-pixel c61ea01092 WelcomeView: wrap Create profile action button in SectionView card
The Create profile action SettingsActionItem at the bottom of the
Create profile screen was loose on canvas. Wrap in SectionView so it
reads as a single-item card matching the iOS-style facelift. The two
SectionTextFooter captions below stay outside the card.

Added missing `import SectionView`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:33:22 -07:00
another-simple-pixel 58eeb66281 UserAddressView: move "contacts remain connected" footer out; pad welcome message field; wrap Save in card
Three SimpleX address fixes:
- "Your contacts will remain connected" SectionTextFooter moved out of
  the DeleteAddressButton SectionView (was rendering inside the card).
- Address settings > welcome message field gets 10dp vertical
  contentPadding on its SectionView so the TextEditor doesn't sit flush
  against the card top/bottom.
- Address settings > Save action wrapped in its own SectionView so it
  reads as a single-item card.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:31:31 -07:00
another-simple-pixel c25f36a900 TagListView: wrap Add/Save list button in SectionView card
The "Add to list" / "Save list" action button in TagListEditor (opened
from chatlist "+" Add list) was a loose SectionItemView on the canvas
with no card chrome. Wrap in SectionView so it reads as a single-item
card. ChatTagInput stays as a form field above.

Added missing `import SectionView`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:27:52 -07:00
another-simple-pixel 4d9319d12a AddGroupView/AddChannelView: wrap action buttons + toggles in SectionView card
In Create group and Create public channel screens the action buttons
(Create / Configure relays) and incognito toggle were rendered as loose
SectionItemViews on the gray canvas with no card chrome. Wrap them in
SectionView so they read as a single card matching the iOS-style facelift.
The display-name input above and the descriptive footer below stay
outside the card (text input keeps its own padding, footer reads as
caption).

Added missing `import SectionView` in AddGroupView.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:26:23 -07:00
another-simple-pixel 3a9ece8d1e NewChatSheet: render filtered contact list inside SectionView card
The "Contacts" header was a SectionView with empty content lambda, and
the actual contact rows were rendered as separate LazyColumn items
OUTSIDE the SectionView — so they sat on canvas without card chrome.

Move filteredContactChats.forEachIndexed { ContactListNavLinkView }
INSIDE the SectionView lambda in both OneHandLazyColumn and
NonOneHandLazyColumn so the contacts read as a single card matching
the iOS-style facelift.

Same trade-off as GroupChatInfoView members fix (fa29bb7a): lazy
rendering of contact rows replaced with eager composition inside a
Column. For typical contact lists (<100) imperceptible; very long
lists may compose slower on open.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:24:35 -07:00
another-simple-pixel b187cf1f85 GroupChatInfoView: move chat-ttl footer caption out of SectionView lambda
Same pre-card-chrome pattern as ChatInfoView (fixed in b1a1dad8):
SectionTextFooter("Delete chat messages from your device.") sat inside
the SectionView around ChatTTLOption, so it rendered inside the white
card after PR #6777 added card chrome. 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 09:16:29 -07:00
another-simple-pixel 772d4f04e2 ServersSummaryView: wrap "Showing info for" dropdown in SectionView card
The user-selection ExposedDropDownSettingRow at the top of the
servers info screen was rendered loose on the canvas with no card
chrome. Wrap in SectionView so it reads as a card matching the rest
of the screen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 09:15:03 -07:00