Skip to content

Chat remains compressed after closing minimized web-tab #2041

@auranebesnew

Description

@auranebesnew

Summary

When navigating from Telegram in-app browser to a chat via a t.me/tg:// link, a minimized web-tab appears at the bottom. After closing it, the chat UI remains compressed, as if the bottom inset was not fully removed.

Environment

Device: iPhone 16e (real device)

iOS version: 26.3

App version: 12.5.2

Steps to Reproduce

  1. Open any external link inside Telegram (in-app browser opens). Image
  2. Tap a t.me/... or tg://... link that navigates to a chat.
  3. Chat opens with a minimized web-tab at the bottom.
Image
  1. Close the bottom web-tab.
  2. Observe that the chat layout is not fully restored.
Image

Expected Result

After closing the minimized web-tab, chat should fully occupy available screen height, insets should be recalculated, and scroll/input areas should match normal chat layout without minimized panel.

Actual Result

The bottom web-tab is closed, but chat remains compressed/shifted

Impact

  • UX: screen appears broken
  • Usability: visible chat content area may be reduced.
  • Navigation quality: browser-to-chat transitions feel unstable.

Scenario

Flow path:

  • BrowserWebContent: intercepts telegram links and calls minimize() + openAppUrl(...).
  • NavigationController: when minimizedContainer exists, it adds bottom inset / reduces available height (updatedSize.height -= minimizedContainerHeight).
  • BrowserScreen: when closing minimized browser, it uses minimizedContainer.removeController(controller).

Potential issue:

  • MinimizedContainerImpl.removeController(...) removes an item locally, but when the last item is removed it does not explicitly dismiss the container lifecycle (willDismiss) and may not trigger a full layout recalculation of the active chat controller.
  • As a result, NavigationController may still keep minimizedContainer != nil, and stale bottom inset remains applied.

Sources:

  • submodules/BrowserUI/Sources/BrowserScreen.swift
  • submodules/TelegramUI/Components/MinimizedContainer/Sources/MinimizedContainer.swift
  • submodules/Display/Source/Navigation/NavigationController.swift

Fix

Make last-item close behavior consistent with full container dismiss:

  1. In MinimizedContainerImpl.removeController(...):
    • after item removal, check items.isEmpty;
    • if empty, call willDismiss?(self) and complete cleanup animation.
  2. Or (additionally/alternatively) in NavigationController:
    • after removing controller from minimized container, if controllers.isEmpty, set self.minimizedContainer = nil and call updateContainersNonReentrant(...).
  3. Ensure a single, reliable cleanup path for minimizedContainer and layout invalidation.

Pseudo-snippet:

public func removeController(_ viewController: MinimizableController) {
    guard let item = self.items.first(where: { $0.controller === viewController }) else {
        return
    }

    self.items.removeAll(where: { $0.id == item.id })

    if self.items.isEmpty {
        self.willDismiss?(self)
        self.requestUpdate(transition: .animated(duration: 0.25, curve: .easeInOut)) { [weak self] _ in
            guard let self else { return }
            self.didDismiss?(self)
        }
    } else {
        self.requestUpdate(transition: .animated(duration: 0.25, curve: .easeInOut))
    }
}

Tests

  1. Manual repro scenario above (single minimized tab).
  2. Multiple minimized tabs:
    • close non-last tab;
    • close last tab.
  3. Repeat browser -> chat -> browser flow multiple times.
  4. Verify portrait/landscape.
  5. Verify with chat keyboard open/closed.
  6. Verify no regression for maximize minimized controller.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions