Skip to content

fix(teams): the invitation-accept screen scrolls itself - #164

Merged
anilcancakir merged 2 commits into
mainfrom
fix/invitation-accept-scrolls
Sep 24, 2026
Merged

anilcancakir merged 2 commits into
mainfrom
fix/invitation-accept-scrolls

Conversation

@anilcancakir

Copy link
Copy Markdown
Member

What

  • The invitation-accept screen wraps its content in its own SingleChildScrollView(primary: false), as MSPageScaffold screens do.
  • MagicStarterLayoutTheme.contentClassName's doc names the stacked-route hazard and recommends 'flex-1 min-h-0' for any app that stacks routes under this layout. The default is unchanged.

Why

This was the one starter screen in the app shell with no scroll of its own. A host whose content box does not scroll (the setting #160 recommends) handed it a bounded height, and on a short viewport the card overflowed with nothing to drag. The default content box scrolls the shell's nested Navigator, which breaks a page left under a .stacked() route on its second hidden rebuild (flutter/flutter#193247). Changing the default would move layout for every existing host, so this documents it instead. Refs #160.

Testing

  • New test: at 390x300 the view overflowed by 76px before the change and renders cleanly after.
  • flutter analyze clean, 1540 tests green, dart format --set-exit-if-changed . clean.
  • Inside a host that already wraps the view in its own scroll (uptizm), the inner scroll view sizes to its child under the unbounded height and never claims a drag, the same as MSPageScaffold.

It was the one starter screen in the app shell with no scroll of its
own, so a host whose content box does not scroll handed it a bounded
height and the card overflowed a short viewport with nothing to drag.
It now sits in its own SingleChildScrollView(primary: false), as the
MSPageScaffold screens do.

contentClassName's doc now names the stacked-route hazard: the default
scrolls the shell's nested Navigator, which breaks a page left under a
.stacked() route on its second hidden rebuild, so an app that stacks
routes should set 'flex-1 min-h-0'. The default is unchanged.

Refs #160
@codecov

codecov Bot commented Sep 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@kodizm

kodizm Bot commented Sep 23, 2026

Copy link
Copy Markdown

Note

Kodizm (AI-generated). May contain mistakes; verify before acting.

The change looks correct: I found no defects.

The view now wraps its state-rendered content in SingleChildScrollView(primary: false), which is the same pattern MSPageScaffold uses. I grepped the view for Expanded, Flexible, Spacer and Center. The only hits were two fixed-height WSpacers, so nothing inside relies on bounded height and the unbounded scroll extent is safe. Using primary: false avoids grabbing the ambient controller, which is the stacked-route hazard the PR describes. The theme change only touches docs, and the default is unchanged.

I read the view diff. I did not open the CHANGELOG, the theme doc comment or the test diff.

Tests

A new test reproduces the overflow at 390x300, which the PR says was 76px before the fix. I did not read it.

CI

  • Lint & Test: success
  • codecov/patch: success
  • Published graph: success
  • Auto-merge low-risk Dependabot PRs: skipped

@kodizm

kodizm Bot commented Sep 24, 2026

Copy link
Copy Markdown

Note

Kodizm (AI-generated). May contain mistakes; verify before acting.

Incremental review of the commits since my last pass (9c7c456 → f668240). This adds a second, related fix: settings/profile/team-create sub-pages resetting their shared controller in onInit were notifying mid-build, which crashed the still-mounted hub with "setState() or markNeedsBuild() called during build". The changes look correct.

The additional commits look correct: I found no defects.

resetQuietly() on both controllers clears validationErrors and calls setState(null, status: RxStatus.empty(), notify: false) directly, bypassing notifyListeners entirely rather than relying on suppression, which is the right fix for a call made during the parent route's build. The eight views that reset their controller in onInit were switched to it consistently, and I checked the two views not touched (magic_starter_team_invitation_accept_view.dart, magic_starter_team_settings_view.dart) — the former only calls clearErrors() (no setEmpty(), and isn't stacked under another view holding the same controller), the latter doesn't reset the controller in onInit at all, so neither needed the change.

The _suppressNotifications flag becoming _suppressionDepth (an int) fixes a real bug: two overlapping withoutNotifying calls previously un-suppressed each other when the first to finish cleared the shared flag. The _loadSessions methods (profile settings and sessions views) now wrap getSessions() in withoutNotifying since it calls setLoading()/notifies before its first await; the profile settings view also gained a missing if (!mounted) return; after the await, matching the sessions view's existing guard.

Tests

New widget tests push every affected sub-page over its parent (hub or team settings) with the controller left in a dirty state, and assert tester.takeException() is null, which is precisely the crash this fixes. New controller unit tests cover the overlapping-suppression fix and resetQuietly's no-notify behaviour directly.

CI

  • Lint & Test: success
  • codecov/patch: success
  • Published graph: success
  • Auto-merge low-risk Dependabot PRs: skipped (not applicable)

head_sha matches the reviewed commit (f668240).

@anilcancakir
anilcancakir merged commit 4425c21 into main Sep 24, 2026
5 checks passed
@anilcancakir
anilcancakir deleted the fix/invitation-accept-scrolls branch September 24, 2026 08:57
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