Skip to content

fix(ios): start opened iPhone Duo panes beside the status cluster - #281

Merged
iebb merged 2 commits into
masterfrom
fix/duo-opened-top-padding
Oct 30, 2026
Merged

iebb merged 2 commits into
masterfrom
fix/duo-opened-top-padding

Conversation

@iebb

@iebb iebb commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Change

On an opened iPhone Duo the clock and status icons sit in a cluster in one corner, but the window's safe area still reserves the cluster's full height across the whole top edge. Every pane's header therefore started far below the top (about 82-95pt), which looked like oversized top padding.

  • AppDelegate.swift answers a new topOcclusionGeometry call on the existing geometry channel with the window's safe top, the status bar bottom and the active occlusion regions (UIView.reservedRegions, behind the existing MITHKA_HAS_RESERVED_REGIONS condition in Duo.xcconfig).
  • lib/app/top_corner_cluster.dart decides when that inset comes only from a corner cluster. Then side-by-side panes start on a shared 24pt band, and header controls keep 8pt clear of the cluster (TopClusterInsets, headerChromePaddingOf). HorizontalSafeViewport reads the geometry again after the window settles (600ms), because the cluster moves after the device opens or turns.
  • Settings in two columns uses the same band. Both column titles share one row and centre line, and each column's colour runs to the top edge.
  • The closed Duo, other iPhones, iPad, and platforms without the method (MissingPluginException) keep their previous insets. preferredVerticalBarBehavior .disabled from 8fa2c1e is unchanged.

Affected platform: iOS (iPhone Duo opened). No user-visible change elsewhere.

Related PRs and canonical PR (or None; existing PRs checked): this is the canonical PR for this change. Open and recently closed PRs were checked; none covers it. It ships alongside #282, #283 and #284, which are independent fixes from the same request. Each touches different code and is useful alone.

Telegram API Terms classification

Follow the contribution and agentic review rules. Select exactly one classification and explain it below.

This is an agentic source-code review classification. Every store version must remain compliant with applicable Telegram API Terms; the guarded-source exception does not apply to store distribution or review.

  • Compliant/unchanged: this change complies with applicable Telegram API Terms, preserves Telegram's basic functionality, and does not introduce behavior covered by section 1.4.
  • Section 1.4 exception: the entire feature is guarded by allowTelegramTosViolations (I_DONT_FUCKING_CARE_ABOUT_TOS), disabled in official builds, and available only in an explicitly enabled self-build.
  • Disallowed or unresolved: this PR must not be approved or merged until its classification and implementation are resolved.

Reason and affected Telegram behavior:
Layout-only change to header insets; no Telegram API usage or behavior changes.

Basic checks (every PR)

Check each item after verification. If a check is inapplicable, explain why in the evidence below before checking it.

  • I reviewed the diff for correctness, unintended behavior, secrets, and unrelated changes.
  • Formatting passed, or I recorded why it is inapplicable: dart format --output=none --set-exit-if-changed lib test integration_test test_driver.
  • Analysis passed, or I recorded why it is inapplicable: flutter analyze.
  • Relevant tests passed, or I recorded why they are inapplicable; name the commands and test cases below. Quality CI runs flutter test --concurrency=4.
  • I checked affected build/platform paths and applicable localization/generated files; list the evidence below.
  • I completed the Terms classification above and verified that official builds cannot enable section 1.4 exceptions.

Commands, results, platform/build/UI evidence, and reasons for inapplicable checks:

  • dart format --output=none --set-exit-if-changed lib test integration_test test_driver with the Dart 3.12.2 SDK from Flutter 3.44.2: 0 changed.
  • dart analyze --fatal-infos (the same analysis server and rules flutter analyze uses, Flutter 3.44.2 SDK): No issues found on this branch alone and on all four PRs combined.
  • flutter test could not run in the authoring sandbox (Alpine/musl host), so the tests box stays unchecked until Quality CI reports on this PR head. No new tests were added, at the maintainer's request.
  • iPhone Duo simulator, opened: chat list, chat and Settings headers start on the 24pt band, header buttons end 8pt before the clock cluster, and the Settings columns are level with no separate band. The designer measured both Settings titles centred at about 47pt, within half a point of each other. Closed: the layout is identical to master.
  • After the device check, two lint-only edits were made: import order in main_tab_view.dart and a math.max tear-off in top_corner_cluster.dart. They do not change behavior.
  • Android, desktop and web are untouched; the Dart side falls back when the native method is absent.
  • Built together with fix(chat): make the formatting panel readable with a bold A button #282, fix(chat): fill the whole tab with the sticker panel switcher highlight #283 and feat(settings): let everyone pick today's penguin icon #284 in one unsigned iOS Simulator archive (Xcode 27, iOS 27 SDK, I_DONT_FUCKING_CARE_ABOUT_TOS=false). Together the four branches match the tested source, apart from two lint-only edits in fix(ios): start opened iPhone Duo panes beside the status cluster #281.

Section 1.4 exception checks

Not applicable: compliant change, no guarded behavior.

  • All UI, routes, commands, callbacks, background work, TDLib/native effects, and registrations use the compile-time guard; a runtime preference alone cannot enable the feature.
  • With the flag omitted, the feature is absent and ordinary Telegram behavior remains intact, including with old saved settings.
  • With --dart-define=I_DONT_FUCKING_CARE_ABOUT_TOS=false, the feature is absent and ordinary Telegram behavior remains intact.
  • With --dart-define=I_DONT_FUCKING_CARE_ABOUT_TOS=true, the feature works through the guarded entry points in a self-build; I included relevant test and build/UI evidence.
  • Official release, nightly, TestFlight, and store builds keep the flag false and have no option that enables it. All store versions remain compliant with applicable Telegram API Terms.

Guard locations and evidence for each flag variant: Not applicable.

Agentic reviewer confirmation

Agentic code reviewer only: record this confirmation in the PR review or check these boxes before approval.

  • I independently confirmed the Terms classification and inspected all required guards and evidence.
  • Applicable checks and Quality CI pass; no unresolved classification or unguarded section 1.4 behavior remains.

On an opened iPhone Duo the clock and status icons sit in one corner, but
the safe area still reserves their full height across the whole top edge,
so every pane's header started far below the top (about 82-95pt).

The runner now reports the live top occlusion geometry (safe top, status
bar bottom and the active occlusion regions) over the geometry channel.
When that inset comes only from a corner cluster, side-by-side panes start
on a shared 24pt band and header controls keep 8pt clear of the cluster.
Settings in two columns follows the same band, so both titles stay level
and each column's colour runs to the top edge.

The closed Duo, other iPhones, iPad and platforms without the method keep
their previous insets.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T20:16:38.972232Z 0c012ad PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0c012ad989

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +191 to +195
final top =
widget.enabled &&
data != null &&
(media.padding.top - data.safeTop).abs() <= 1
? data.compactTop

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize native geometry to the scaled Flutter viewport

On an opened Duo with a non-default Interface Size preference, this comparison prevents the compact band from activating: main.dart places HorizontalSafeViewport inside ScaledAppView, which divides MediaQuery.padding by interfaceScale, whereas data.safeTop remains in native window points. For example, an 88pt native inset becomes 80 logical pixels at scale 1.1, failing the one-pixel tolerance and retaining the oversized top gap this change addresses. Normalize the native geometry into the pane's coordinate system before comparing and measuring it; the horizontal measurement also mixes the transformed localToGlobal origin with the untransformed box.size.

Useful? React with 👍 / 👎.

Comment thread lib/chat/chat_view.dart
Comment on lines +8546 to 8550
// panels below it keep the full width.
padding:
const EdgeInsets.symmetric(horizontal: 14) +
TopClusterInsets.of(context),
child: Row(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear the cluster for panels below the chat toolbar

When the corner cluster extends below the toolbar, reserving horizontal clearance only for this row leaves the following controls underneath system chrome. At the default interface scale, the new 24pt band plus the default 48pt chat toolbar puts _chatTranslationPanel() at y=72, while the opened-Duo cluster described in this commit reaches approximately 82–95pt. ChatTranslationPanel places its language and dismiss buttons at the right edge of that 40pt row, so a right-corner cluster overlaps those controls. Apply clearance to subsequent rows that still intersect the occlusion region, or keep them below its bottom, rather than assuming everything below the toolbar is clear.

Useful? React with 👍 / 👎.

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Automated PR review

Head: 2ebfde8303e66c6a8b6f7fb767d3f8f6d1d3fdfe · master: 73c1d46bb5a726e68c9bef160ccaf72a27725ef1
LLM recommendation: needs_human. This is not a GitHub approval.
Auto-merge: blocked. Only iebb can authorize the current head.

Review unavailable: Incomplete model answer (length); manual review required.

Remaining gates

  • Waiting for iebb to approve this exact current head.
  • Complete the basic check: Relevant tests passed.
  • Resolve all review threads before auto-merge.
  • All current head checks must complete successfully (no skipped/neutral substitutes).
  • master source incomplete: ios/Runner/AppDelegate.swift
  • head source incomplete: ios/Runner/AppDelegate.swift
  • master source incomplete: lib/app/main_tab_view.dart
  • head source incomplete: lib/app/main_tab_view.dart
  • master source incomplete: lib/channels/topic_chat_view.dart
  • head source incomplete: lib/channels/topic_chat_view.dart
  • Context budget reached; remaining source omitted.

No PR code runs with the model key or write token. Free-only routing; provider/rate-limit failures never authorize a merge. Existing review findings must be resolved, not hidden by a new recommendation.

The interface size screen's header uses the same corner-cluster padding as
the other headers. It was missing from this PR and landed in #284 instead.
iebb added a commit that referenced this pull request Oct 29, 2026
headerChromePaddingOf comes from the Duo top padding change (#281); this PR
keeps the existing header inset so it builds on its own.
@iebb
iebb merged commit 0ef96ee into master Oct 30, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant