Commit Graph

1408 Commits

Author SHA1 Message Date
another-simple-pixel ba2a2a2ebd Card-less screens: paint background with Material surface
Form-only and link/QR screens have no card sections — the off-white canvas
under them just adds an extra visual layer with nothing to lift. Switch
their background to MaterialTheme.colors.surface (white on LIGHT, palette
surface on DARK/BLACK/SIMPLEX) so the screen reads as a single sheet.

Two patterns by container:
- 11 ModalView callsites get background = MaterialTheme.colors.surface.
- 4 screens rendered inside someone else's ModalView (GroupLinkView,
  HiddenProfileView, TagListView, UserProfilesView) wrap their root
  ColumnWithScrollBar in Box(Modifier.fillMaxSize().background(...))
  so they own their background regardless of caller.
- 1 BottomSheet root (CreateProfile in WelcomeView) gets background on
  the fillMaxSize Box.

Touched screens: Create profile, Create first profile (mobile/desktop),
Create group, Create channel (3 wizard steps), Edit group profile,
Group link, Add welcome message / Welcome message, Edit own profile,
Hide profile, Tag list editor, Your chat profiles, Add server,
Add chat relay (new variant only — Edit relay stays settings-style).
2026-05-18 09:29:20 -07:00
another-simple-pixel 0bccc32728 Theme: darken LightColorPalette.secondaryVariant from #F1F2F6 (LightGray) to #E0E0E0
Old value (LightGray = #F1F2F6) was nearly invisible against the ~#F0F0F0
canvas — slightly bluish hue, ~1-2 units of contrast. The new #E0E0E0 sits
~16 units below canvas and ~31 below white card, visible on both. Affects
all LIGHT-theme avatar placeholders, UserPicker icons, DevicePill borders
and a handful of subtle UI surfaces using secondaryVariant.
2026-05-18 08:10:46 -07:00
another-simple-pixel cc26dcfe4c Revert "ChatInfoImage: LIGHT default avatar at midpoint of white card and gray canvas"
This reverts commit 05fbd6e0b1.
2026-05-18 07:51:15 -07:00
another-simple-pixel f1d80307f6 Revert "MemberProfileImage: use defaultProfileIconColor instead of secondaryVariant"
This reverts commit bea3f24664.
2026-05-18 07:50:57 -07:00
another-simple-pixel 1923b87240 Revert "ProfileImage colors: split into card vs canvas variants"
This reverts commit 379f84a4ae.
2026-05-18 07:50:39 -07:00
another-simple-pixel 13d6bca1b3 GroupChatInfoView: move owner row out of the members card into the lazy list
Per review #1: card holds only Invite + (optional) search; the user-as-owner
row joins the same lazy column as the rest of the members, picking up the
canvas-variant avatar color through MemberProfileImage's updated default.
2026-05-18 07:47:11 -07:00
another-simple-pixel 379f84a4ae ProfileImage colors: split into card vs canvas variants
Revert defaultProfileIconColor back to 0.91 mix (~#E8) — that's the right
amount of contrast against a white SectionView card. Add a sibling helper
defaultProfileIconColorOnCanvas() at 0.85 mix (~#D9), which sits 23 units
below the ~#F0 canvas — same absolute contrast as the card variant achieves
on white.

Switch MemberProfileImage default from defaultProfileIconColor to the canvas
variant. Member avatars almost always render on canvas (chat list rows,
chat-bubble author avatar, group members list outside the card, channel
members, channel relays). Callers that need the card variant pass an
explicit color.
2026-05-18 07:46:12 -07:00
another-simple-pixel bea3f24664 MemberProfileImage: use defaultProfileIconColor instead of secondaryVariant
MemberProfileImage hard-coded color = MaterialTheme.colors.secondaryVariant
as default, which is LightGray (#F1F2F6) on LIGHT — slightly bluish and
nearly invisible against the ~#F0F0F0 canvas. Reuse the defaultProfileIconColor()
helper so the LIGHT default matches the rest of the app (midpoint between
canvas and white card), and DARK themes keep their palette secondaryVariant.

defaultProfileIconColor() in ChatInfoImage.kt promoted from private to file-
level visibility so it can be referenced from GroupMemberInfoView.
2026-05-18 07:42:07 -07:00
another-simple-pixel 05fbd6e0b1 ChatInfoImage: LIGHT default avatar at midpoint of white card and gray canvas
Was at 0.91 mix (~#E8) — designed to sit 'below' the white card, but on the
~#F0 canvas it nearly blended (delta ~8). Switch to 0.97 mix (~#F7), which
is the geometric midpoint between #FF (white card) and ~#F0 (canvas) and so
sits at equal absolute contrast against either background.
2026-05-18 06:53:50 -07:00
another-simple-pixel afa57462a1 GroupChatInfoView: keep Invite + owner in card, render members as lazy items
fa29bb7a7 put filteredMembers.value.forEach inside the same SectionView as
the Invite button and the owner row to get a unified card visual. That
sacrificed lazy rendering — all members composed at once, hurting big-group
scroll perf. Founder asked to bring lazy back.

Compromise: keep Invite + (search row) + owner row inside the SectionView
card (the 'hero' rows). Move the rest of the members out to a sibling
items(filteredMembers.value, key = { it.groupMemberId }) call in the
parent LazyColumn — bare SectionItemViewLongClickable rows below the card,
lazy-composed by LazyColumn.
2026-05-18 04:24:04 -07:00
another-simple-pixel f7cdcac576 NewChatSheet: render filtered contacts in search mode (regression fix)
Commit 3a9ece8d1 moved contacts forEach inside the if-branch and made the
else-branch fall back to NoFilteredContactsItem. That broke search: when
the user typed text and the filter returned non-empty results, the
if-condition (filtered.isNotEmpty() && searchText.isEmpty()) was false,
the else ran NoFilteredContactsItem, NoFilteredContactsItem's internal
guard saw a non-empty filter and rendered nothing — search results disappeared.

Restore three-way branching with when{}: header + contacts in card when
no search; contacts in plain card when search has matches; NoFilteredContactsItem
when filter is empty. Applied at both OneHandLazyColumn and the regular layout.
2026-05-18 04:21:08 -07:00
another-simple-pixel 9f794f549c Sections: normalize redundant SectionDividerSpaced flag combinations
After founder simplified SectionDividerSpaced to one Spacer height (any flag
true -> DEFAULT_PADDING; both false -> DEFAULT_PADDING_HALF), many call sites
still pass combinations like (maxTopPadding = true) or
(maxTopPadding = true, maxBottomPadding = false) that all produce the same
20dp gap as the default. The flag names no longer match what they do —
reviewer flagged this as misleading.

Collapse all call sites to two canonical forms: SectionDividerSpaced() for
the 20dp gap, SectionDividerSpaced(maxBottomPadding = false) for the 10dp
tight gap. Behavior identical. Function signature kept (founder's API).
2026-05-18 04:18:00 -07:00
another-simple-pixel 2f76445e66 ConnectMobileView: collapse double blank line left over from move-footer edit 2026-05-18 04:14:30 -07:00
another-simple-pixel c924c13297 Theme: document why canvasColorForCurrentTheme reads CurrentColors.value directly
Reviewer asked why this helper uses CurrentColors.value.base instead of the
Compose MaterialTheme/CompositionLocal route. Reason is that the helper is
intentionally callable from both @Composable bodies and DrawScope (inside
sectionItemDivider's drawWithContent), and DrawScope can't invoke @Composable
getters. Add a paragraph to the doc-comment so future readers don't try to
'fix' it back to MaterialTheme.colors and break the divider draw path.
2026-05-18 04:13:14 -07:00
another-simple-pixel 5c4a24f15e Section / Theme: extract sectionCardColor() helper
Three SectionView overloads were each computing the same cardColor inline:
if (CurrentColors.value.base == DefaultTheme.LIGHT) Color.White
else MaterialTheme.colors.background.mixWith(...). DRY violation paired with
the canvasColorForCurrentTheme() helper that already covers the canvas side
of the same theme split. Add a sectionCardColor() function in Theme.kt and
collapse the 3 inline formulas to one call.
2026-05-18 04:12:05 -07:00
another-simple-pixel f99cf9b881 Revert UserPicker to pre-card-wraps state per founder's request
Restore UserPicker.kt and UserPicker.android.kt to their state at 43855ae07
(before commit 3a7118235 introduced SectionView wraps). The founder asked in
chat to keep UserPicker out of the cards facelift — undo all of our changes
to it, including the followup tweaks (avatar padding, divider above grid,
active-profile wrap, etc.) and the founder's own followup cleanup 23b0e41d8
which only existed to refactor our wraps.
2026-05-18 02:48:38 -07:00
another-simple-pixel b3184a1285 Strings: convert settings_section_title_interface to sentence case (Interface) 2026-05-18 01:59:00 -07:00
another-simple-pixel 710aba103b Strings: convert group_info_section_title_num_members to sentence case 2026-05-18 01:58:44 -07:00
another-simple-pixel d8d7578676 ServersSummaryView: Message reception header bottom padding 5dp -> 8dp to match SectionView default 2026-05-18 01:58:27 -07:00
another-simple-pixel 6d29d2a658 Sections: drop card-title weight from SemiBold to Medium (W500) 2026-05-18 01:58:11 -07:00
another-simple-pixel 5583c0e7b1 Sections: add SemiBold weight to card titles across all 4 places 2026-05-18 01:57:52 -07:00
another-simple-pixel cbae448309 ServersSummaryView: bump Message reception custom header to 14sp to match other card titles 2026-05-18 01:57:32 -07:00
another-simple-pixel f88bcf0081 Section: bump card-title font size from 12sp to 14sp across all 3 SectionView variants 2026-05-18 01:57:10 -07:00
another-simple-pixel a15a2ca625 UserPicker: add top spacer above active profile card and tighten its left padding
Card was flush against the sheet's top edge; add DEFAULT_PADDING spacer above. Left padding inside the card was 16dp while the avatar (60dp) sat in an 80dp minHeight row so visual top/bottom were ~10dp — bring start down to 10dp so the photo sits equidistant from card top, bottom and left.
2026-05-18 01:56:49 -07:00
another-simple-pixel dd38646996 Strings: convert section-title resources from ALL CAPS to sentence case
26 section header strings used as SectionView titles (SETTINGS, CHAT DATABASE, HELP, SERVERS, etc.) were stored ALL CAPS in source. The .uppercase() removal commit did nothing for them. Convert the source values to sentence case with proper-noun preservation (SimpleX, SOCKS). LIVE and OK stay all-caps (status badge and button).
2026-05-18 01:56:27 -07:00
another-simple-pixel 7c37f898d5 UserPicker: restore SectionView wrap around desktop active-profile row
Commit 3a7118235 extracted the profile out of its original SectionView when wrapping the menu in its own card. Without the card chrome the profile shifted to the screen edge instead of sitting at CARD_PADDING like the menu below. Wrap it back in SectionView and add SectionDividerSpaced before the menu card.
2026-05-18 01:56:07 -07:00
another-simple-pixel 1ff5b3d36b ChatListNavLinkView.desktop: restore chat list dividers outside SectionView
Commit 633e0f414 made SectionDivider() a no-op outside SectionView card, which removed the desktop chat list dividers (the list is not wrapped in a SectionView). Mirror the Android conditional: SectionDivider in-card, padded Divider otherwise.
2026-05-18 01:55:46 -07:00
another-simple-pixel 963140e9a0 UserPicker.android: align profile boxes with menu card left edge (CARD_PADDING) 2026-05-18 01:55:26 -07:00
another-simple-pixel 426208fdda Appearance: shrink ColorModeSwitcher tap target to keep UserPicker Settings row at standard 58dp height 2026-05-18 01:55:04 -07:00
another-simple-pixel c6f85c68fd Section: shrink icon-to-text spacing to 5dp (-3dp from previous 8dp) 2026-05-18 01:54:44 -07:00
another-simple-pixel 6a898550c1 Sections: drop .uppercase() from all section / header titles
Source string resources are already in sentence case (e.g. "Profile images", "Message reception"). The .uppercase() calls forced them to ALL CAPS, which is the Android settings convention but conflicts with the iOS-style facelift. Remove the call everywhere so headers render as in the source.
2026-05-18 01:54:22 -07:00
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