mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-07-28 16:29:49 +00:00
android, desktop: remove stray card dividers in server info, connect-to-desktop, appearance and migration screens (#7118)
* android, desktop: remove stray card dividers in server info, connect-to-desktop, appearance and migration screens PR #6777 turned these into card screens, where SectionView draws a 2dp near-black divider between every direct child, but left content patterns that pre-date the card chrome: nested SectionViews (SMP/XFTP server detail), loose Text + Spacer + Text (connect-to-desktop device name and version), and a SectionDividerSpaced() as a middle child (Appearance with an image wallpaper, migrate-from-device "error stopping chat"). Each draws stray lines inside the card, most visible in dark/black themes. Restructure to the sibling pattern already used by DetailedSMPStatsLayout: un-nest the server-detail sub-sections (address its own card, stats/subs/sessions as siblings; subscription rows carded), wrap each device name/version block in a single Column, and drop the in-card spacers (the adjacent-row auto-divider already separates them). Layout-only; iOS is a separate codebase and is unaffected. * docs: add plan justifying removing stray card section dividers
This commit is contained in:
+21
-31
@@ -367,7 +367,7 @@ private fun SMPSubscriptionsSection(subs: SMPServerSubs, summary: SMPServerSumma
|
||||
)
|
||||
SubscriptionStatusIndicatorView(subs, summary.sessionsOrNew.hasSess)
|
||||
}
|
||||
Column(Modifier.padding(PaddingValues()).fillMaxWidth()) {
|
||||
SectionView {
|
||||
InfoRow(
|
||||
generalGetString(MR.strings.servers_info_subscriptions_connections_subscribed),
|
||||
numOrDash(subs.ssActive)
|
||||
@@ -540,20 +540,16 @@ fun XFTPServerSummaryLayout(summary: XFTPServerSummary, statsStartedAt: Instant,
|
||||
)
|
||||
)
|
||||
}
|
||||
if (summary.stats != null || summary.sessions != null) {
|
||||
SectionDividerSpaced()
|
||||
}
|
||||
}
|
||||
|
||||
if (summary.stats != null) {
|
||||
XFTPStatsView(stats = summary.stats, rh = rh, statsStartedAt = statsStartedAt)
|
||||
if (summary.sessions != null) {
|
||||
SectionDividerSpaced()
|
||||
}
|
||||
}
|
||||
if (summary.stats != null) {
|
||||
SectionDividerSpaced()
|
||||
XFTPStatsView(stats = summary.stats, rh = rh, statsStartedAt = statsStartedAt)
|
||||
}
|
||||
|
||||
if (summary.sessions != null) {
|
||||
ServerSessionsView(summary.sessions)
|
||||
}
|
||||
if (summary.sessions != null) {
|
||||
SectionDividerSpaced()
|
||||
ServerSessionsView(summary.sessions)
|
||||
}
|
||||
|
||||
SectionBottomSpacer()
|
||||
@@ -572,27 +568,21 @@ fun SMPServerSummaryLayout(summary: SMPServerSummary, statsStartedAt: Instant, r
|
||||
)
|
||||
)
|
||||
}
|
||||
if (summary.stats != null || summary.subs != null || summary.sessions != null) {
|
||||
SectionDividerSpaced()
|
||||
}
|
||||
}
|
||||
|
||||
if (summary.stats != null) {
|
||||
SMPStatsView(stats = summary.stats, remoteHostInfo = rh, statsStartedAt = statsStartedAt)
|
||||
if (summary.subs != null || summary.sessions != null) {
|
||||
SectionDividerSpaced()
|
||||
}
|
||||
}
|
||||
if (summary.stats != null) {
|
||||
SectionDividerSpaced()
|
||||
SMPStatsView(stats = summary.stats, remoteHostInfo = rh, statsStartedAt = statsStartedAt)
|
||||
}
|
||||
|
||||
if (summary.subs != null) {
|
||||
SMPSubscriptionsSection(subs = summary.subs, summary = summary, rh = rh)
|
||||
if (summary.sessions != null) {
|
||||
SectionDividerSpaced()
|
||||
}
|
||||
}
|
||||
if (summary.subs != null) {
|
||||
SectionDividerSpaced()
|
||||
SMPSubscriptionsSection(subs = summary.subs, summary = summary, rh = rh)
|
||||
}
|
||||
|
||||
if (summary.sessions != null) {
|
||||
ServerSessionsView(summary.sessions)
|
||||
}
|
||||
if (summary.sessions != null) {
|
||||
SectionDividerSpaced()
|
||||
ServerSessionsView(summary.sessions)
|
||||
}
|
||||
|
||||
SectionBottomSpacer()
|
||||
|
||||
-1
@@ -196,7 +196,6 @@ private fun MutableState<MigrationFromState>.ChatStopInProgressView() {
|
||||
private fun MutableState<MigrationFromState>.ChatStopFailedView(reason: String) {
|
||||
SectionView(stringResource(MR.strings.error_stopping_chat)) {
|
||||
Text(reason)
|
||||
SectionDividerSpaced()
|
||||
SettingsActionItemWithContent(
|
||||
icon = painterResource(MR.images.ic_report_filled),
|
||||
text = stringResource(MR.strings.auth_stop_chat),
|
||||
|
||||
+21
-10
@@ -147,8 +147,11 @@ private fun ConnectDesktop(deviceName: String, remoteCtrls: SnapshotStateList<Re
|
||||
private fun ConnectingDesktop(session: RemoteCtrlSession, rc: RemoteCtrlInfo?) {
|
||||
AppBarTitle(stringResource(MR.strings.connecting_to_desktop))
|
||||
SectionView(stringResource(MR.strings.connecting_to_desktop), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) {
|
||||
CtrlDeviceNameText(session, rc)
|
||||
CtrlDeviceVersionText(session)
|
||||
Column {
|
||||
CtrlDeviceNameText(session, rc)
|
||||
Spacer(Modifier.height(DEFAULT_PADDING_HALF))
|
||||
CtrlDeviceVersionText(session)
|
||||
}
|
||||
}
|
||||
|
||||
if (session.sessionCode != null) {
|
||||
@@ -223,10 +226,12 @@ private fun FoundDesktop(
|
||||
}
|
||||
SectionDividerSpaced()
|
||||
SectionView(stringResource(MR.strings.found_desktop), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) {
|
||||
CtrlDeviceNameText(session, rc)
|
||||
CtrlDeviceVersionText(session)
|
||||
if (!compatible) {
|
||||
Text(stringResource(MR.strings.not_compatible), color = MaterialTheme.colors.error)
|
||||
Column {
|
||||
CtrlDeviceNameText(session, rc)
|
||||
CtrlDeviceVersionText(session)
|
||||
if (!compatible) {
|
||||
Text(stringResource(MR.strings.not_compatible), color = MaterialTheme.colors.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,8 +260,11 @@ private fun FoundDesktop(
|
||||
private fun VerifySession(session: RemoteCtrlSession, rc: RemoteCtrlInfo?, sessCode: String, remoteCtrls: SnapshotStateList<RemoteCtrlInfo>) {
|
||||
AppBarTitle(stringResource(MR.strings.verify_connection))
|
||||
SectionView(stringResource(MR.strings.connected_to_desktop), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) {
|
||||
CtrlDeviceNameText(session, rc)
|
||||
CtrlDeviceVersionText(session)
|
||||
Column {
|
||||
CtrlDeviceNameText(session, rc)
|
||||
Spacer(Modifier.height(DEFAULT_PADDING_HALF))
|
||||
CtrlDeviceVersionText(session)
|
||||
}
|
||||
}
|
||||
|
||||
SectionDividerSpaced()
|
||||
@@ -308,8 +316,11 @@ private fun CtrlDeviceVersionText(session: RemoteCtrlSession) {
|
||||
private fun ActiveSession(session: RemoteCtrlSession, rc: RemoteCtrlInfo, close: () -> Unit) {
|
||||
AppBarTitle(stringResource(MR.strings.connected_to_desktop))
|
||||
SectionView(stringResource(MR.strings.connected_desktop), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) {
|
||||
Text(rc.deviceViewName)
|
||||
CtrlDeviceVersionText(session)
|
||||
Column {
|
||||
Text(rc.deviceViewName)
|
||||
Spacer(Modifier.height(DEFAULT_PADDING_HALF))
|
||||
CtrlDeviceVersionText(session)
|
||||
}
|
||||
}
|
||||
|
||||
if (session.sessionCode != null) {
|
||||
|
||||
-1
@@ -561,7 +561,6 @@ object AppearanceScope {
|
||||
color = if (chatModel.remoteHostId != null && themeUserDestination.value != null) MaterialTheme.colors.secondary else MaterialTheme.colors.primary
|
||||
)
|
||||
}
|
||||
SectionDividerSpaced()
|
||||
}
|
||||
|
||||
val state: State<DefaultThemeMode?> = remember(appPrefs.currentTheme.get()) {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# Fix stray card dividers in server info, connect-to-desktop, appearance and migration screens
|
||||
|
||||
Branch: `nd/fix-ui-lines` · base: `master`.
|
||||
|
||||
## Problem
|
||||
|
||||
On several card screens (Android and desktop, current `master`), near-black horizontal lines appear inside section cards where they don't belong — most visible in dark/black themes:
|
||||
|
||||
- **Servers info → tap an SMP or XFTP server**: the server-detail card is sliced by stray lines around its nested stats / subscriptions / sessions blocks.
|
||||
- **Use from desktop → "Connected to desktop"** (also the connecting / found / verify states): two black lines between the desktop name and its version (e.g. "Desktop" and "v7.0.0.1").
|
||||
- **Settings → Appearance** with a custom image wallpaper: a double line with a gap between "Remove image" and "Color mode".
|
||||
- **Migrate from this device**, "error stopping chat" state: a double line between the error text and the stop-chat action.
|
||||
|
||||
Behaviour is correct everywhere; the bugs are purely visual.
|
||||
|
||||
## Cause
|
||||
|
||||
PR #6777 (`df5ea3d46`, "android, desktop: new settings section design") wrapped `SectionView`'s content in `CardColumnLayout`, which draws a 2 dp divider (`canvasColorForCurrentTheme()`, near-black in dark/black themes) at the bottom of every direct child except the last. The same PR turned these screens into card screens (`ModalView(cardScreen = true)`) but left three content patterns that pre-date the card chrome, each of which now produces stray lines:
|
||||
|
||||
1. **Nested `SectionView`s** inside one outer `SectionView` (server detail) → card-in-card, plus a line around every nested block and spacer.
|
||||
2. **Loose `Text` + `Spacer` + `Text`** as separate children of a card `SectionView` (connect-to-desktop name + version) → a line after the text and after the spacer.
|
||||
3. **`SectionDividerSpaced()` as a middle child** (Appearance, migration) → on a card screen this is a 30 dp `Spacer`, so it gets a line above *and* below = a double line bracketing a gap.
|
||||
|
||||
This is the same bug class as `2026-05-25-fix-e2e-encryption-section-divider.md` (#7012); #6777 reintroduced further instances that earlier fix did not cover.
|
||||
|
||||
## Fix
|
||||
|
||||
`apps/multiplatform/common/...`, layout-only, matching the reference sibling pattern already used by `DetailedSMPStatsLayout`:
|
||||
|
||||
- **`ServersSummaryView.kt`** — `SMPServerSummaryLayout` / `XFTPServerSummaryLayout`: stop wrapping everything in one outer `SectionView`; make the address its own card and each sub-section a top-level sibling separated by `SectionDividerSpaced()` placed *between* them. `SMPSubscriptionsSection`'s rows are wrapped in their own `SectionView` so they keep card chrome.
|
||||
- **`ConnectDesktopView.kt`** — wrap each device-name + version block in a single `Column` (4 states), so the card sees one child and draws no internal divider.
|
||||
- **`Appearance.kt`** / **`MigrateFromDevice.kt`** — delete the in-card `SectionDividerSpaced()`; the auto-divider between the two now-adjacent rows already separates them (the #6777 precedent for in-card spacers).
|
||||
|
||||
## Risk
|
||||
|
||||
- Layout-only: no logic, state, side-effect, or click-handler change.
|
||||
- iOS is a separate codebase (native grouped lists) and is unaffected.
|
||||
- Verified: `:common:compileKotlinDesktop` and the full desktop AppImage build succeed, and the running app renders the screens correctly. Independent adversarial review confirmed every conditional branch and separator is preserved across all stats/subs/sessions combinations.
|
||||
- Deliberately out of scope: `SectionTextFooter`-inside-card instances (NetworkAndServers, Migrate*) — these render as a single normal row-separator above an in-card caption, not the stray-line bug; a separate #6777-style cleanup.
|
||||
- Rollback: `git revert` the fix commit.
|
||||
Reference in New Issue
Block a user