fix: reset focus after compose pop to prevent web freeze, show snackbar before pop, skip animation replay on thread reload

This commit is contained in:
Patrick Britton 2026-02-08 14:48:44 -06:00
parent 628bdf3c40
commit e03442f789
7 changed files with 27 additions and 17 deletions

View file

@ -460,11 +460,12 @@ class _ComposeScreenState extends ConsumerState<ComposeScreen> {
if (mounted) {
ref.read(feedRefreshProvider.notifier).increment();
Navigator.of(context).pop(true);
// Show snackbar BEFORE pop after pop the context is defunct on web
sojornSnackbar.showSuccess(
context: context,
message: 'Post published',
);
if (mounted) Navigator.of(context).pop(true);
}
} on ToneCheckException {
setState(() {

View file

@ -81,13 +81,14 @@ class _FeedPersonalScreenState extends ConsumerState<FeedPersonalScreen> {
);
}
void _openChainComposer(Post post) {
Navigator.of(context).push(
void _openChainComposer(Post post) async {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ComposeScreen(chainParentPost: post),
fullscreenDialog: true,
),
);
FocusManager.instance.primaryFocus?.unfocus();
}
@override

View file

@ -127,13 +127,14 @@ class _FeedsojornScreenState extends ConsumerState<FeedsojornScreen> {
);
}
void _openChainComposer(Post post) {
Navigator.of(context).push(
void _openChainComposer(Post post) async {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ComposeScreen(chainParentPost: post),
fullscreenDialog: true,
),
);
FocusManager.instance.primaryFocus?.unfocus();
}
void _openAuthorProfile(Post post) {

View file

@ -48,6 +48,7 @@ class _ThreadedConversationScreenState extends ConsumerState<ThreadedConversatio
final Map<String, bool> _likedByPost = {};
final Map<String, bool> _savedByPost = {};
final Set<String> _nsfwRevealed = {};
bool _initialLoadDone = false;
bool _shouldBlurPost(Post post) {
if (!post.isNsfw || _nsfwRevealed.contains(post.id)) return false;
@ -131,13 +132,13 @@ class _ThreadedConversationScreenState extends ConsumerState<ThreadedConversatio
_seedReactionState(focusContext);
// Trigger a rebuild to show the seeded reactions
if (mounted) {
setState(() {});
}
// Only animate on initial load, not on reload after posting
if (!_initialLoadDone) {
_initialLoadDone = true;
_slideController.forward(from: 0);
_fadeController.forward(from: 0);
}
}
} catch (e) {
if (mounted) {
setState(() {
@ -691,6 +692,8 @@ class _ThreadedConversationScreenState extends ConsumerState<ThreadedConversatio
builder: (context) => ComposeScreen(chainParentPost: post),
),
);
// Reset focus so the underlying screen is interactive on web
FocusManager.instance.primaryFocus?.unfocus();
if (result == true) {
_loadFocusContext();
}

View file

@ -681,13 +681,14 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen>
);
}
void _openChainComposer(Post post) {
Navigator.of(context).push(
void _openChainComposer(Post post) async {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ComposeScreen(chainParentPost: post),
fullscreenDialog: true,
),
);
FocusManager.instance.primaryFocus?.unfocus();
}
List<Post> _getPostsFor(ProfileFeedType type) {

View file

@ -440,13 +440,14 @@ class _ViewableProfileScreenState extends ConsumerState<ViewableProfileScreen>
);
}
void _openChainComposer(Post post) {
Navigator.of(context).push(
void _openChainComposer(Post post) async {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ComposeScreen(chainParentPost: post),
fullscreenDialog: true,
),
);
FocusManager.instance.primaryFocus?.unfocus();
}
Future<void> _openMessage() async {

View file

@ -41,13 +41,15 @@ class ComposeAndChatFab extends StatelessWidget {
FloatingActionButton(
heroTag: composeHeroTag,
tooltip: 'Compose',
onPressed: () {
Navigator.of(context).push(
onPressed: () async {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => const ComposeScreen(),
fullscreenDialog: true,
),
);
// Reset focus so the underlying screen is interactive on web
FocusManager.instance.primaryFocus?.unfocus();
},
backgroundColor: AppTheme.brightNavy,
child: const Icon(Icons.edit_outlined, color: AppTheme.white),